فهرست منبع

Merge branch 'beta'

Ugochukwu Mmaduekwe 6 سال پیش
والد
کامیت
af58013e2f
71فایلهای تغییر یافته به همراه5612 افزوده شده و 3652 حذف شده
  1. 43 38
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  2. 18 13
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.TestInsight.dpr
  3. 18 13
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  4. 35 47
      CryptoLib.Tests/src/Asn1/OIDTests.pas
  5. 2 2
      CryptoLib.Tests/src/Math/EC/FixedPointTests.pas
  6. 85 0
      CryptoLib.Tests/src/Math/ECNRTests.pas
  7. 167 11
      CryptoLib.Tests/src/Math/ECPointTests.pas
  8. 21 28
      CryptoLib/src/Asn1/ClpAsn1Objects.pas
  9. 90 0
      CryptoLib/src/Asn1/CryptLib/ClpCryptLibObjectIdentifiers.pas
  10. 184 203
      CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas
  11. 78 67
      CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTNamedCurves.pas
  12. 48 42
      CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas
  13. 1 1
      CryptoLib/src/Crypto/Generators/ClpDHKeyGeneratorHelper.pas
  14. 1 1
      CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas
  15. 1 1
      CryptoLib/src/Crypto/Generators/ClpDsaKeyPairGenerator.pas
  16. 3 3
      CryptoLib/src/Crypto/Generators/ClpECKeyPairGenerator.pas
  17. 1 1
      CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas
  18. 102 45
      CryptoLib/src/Crypto/Signers/ClpECNRSigner.pas
  19. 6 0
      CryptoLib/src/Include/CryptoLib.inc
  20. 4 0
      CryptoLib/src/Include/CryptoLibHelper.inc
  21. 1 1
      CryptoLib/src/Interfaces/ClpICurve25519Custom.pas
  22. 19 2
      CryptoLib/src/Interfaces/ClpIECC.pas
  23. 2 0
      CryptoLib/src/Interfaces/ClpIECNRSigner.pas
  24. 47 0
      CryptoLib/src/Interfaces/ClpIEndoPreCompInfo.pas
  25. 4 4
      CryptoLib/src/Interfaces/ClpIGlvTypeAEndomorphism.pas
  26. 14 17
      CryptoLib/src/Interfaces/ClpIGlvTypeAParameters.pas
  27. 0 2
      CryptoLib/src/Interfaces/ClpIGlvTypeBEndomorphism.pas
  28. 4 15
      CryptoLib/src/Interfaces/ClpIGlvTypeBParameters.pas
  29. 30 3
      CryptoLib/src/Interfaces/ClpIMultipliers.pas
  30. 52 0
      CryptoLib/src/Interfaces/ClpIScalarSplitParameters.pas
  31. 5 4
      CryptoLib/src/Interfaces/ClpIScaleXNegateYPointMap.pas
  32. 3 7
      CryptoLib/src/Interfaces/ClpIScaleYNegateXPointMap.pas
  33. 1 1
      CryptoLib/src/Interfaces/ClpISecP256K1Custom.pas
  34. 1 1
      CryptoLib/src/Interfaces/ClpISecP256R1Custom.pas
  35. 1 1
      CryptoLib/src/Interfaces/ClpISecP384R1Custom.pas
  36. 1 1
      CryptoLib/src/Interfaces/ClpISecP521R1Custom.pas
  37. 1 1
      CryptoLib/src/Interfaces/ClpISecT283Custom.pas
  38. 2 2
      CryptoLib/src/Interfaces/ClpIValidityPrecompInfo.pas
  39. 18 0
      CryptoLib/src/Interfaces/ClpIWNafPreCompInfo.pas
  40. 242 973
      CryptoLib/src/Math/EC/ClpECAlgorithms.pas
  41. 311 72
      CryptoLib/src/Math/EC/ClpECC.pas
  42. 1534 0
      CryptoLib/src/Math/EC/ClpECCompUtilities.pas
  43. 56 0
      CryptoLib/src/Math/EC/ClpScaleXNegateYPointMap.pas
  44. 56 0
      CryptoLib/src/Math/EC/ClpScaleYNegateXPointMap.pas
  45. 51 12
      CryptoLib/src/Math/EC/Custom/Djb/ClpCurve25519Custom.pas
  46. 44 9
      CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256K1Custom.pas
  47. 44 9
      CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256R1Custom.pas
  48. 44 9
      CryptoLib/src/Math/EC/Custom/Sec/ClpSecP384R1Custom.pas
  49. 43 8
      CryptoLib/src/Math/EC/Custom/Sec/ClpSecP521R1Custom.pas
  50. 105 24
      CryptoLib/src/Math/EC/Custom/Sec/ClpSecT283Custom.pas
  51. 75 0
      CryptoLib/src/Math/EC/Endo/ClpEndoPreCompInfo.pas
  52. 92 0
      CryptoLib/src/Math/EC/Endo/ClpGlvTypeAEndomorphism.pas
  53. 81 0
      CryptoLib/src/Math/EC/Endo/ClpGlvTypeAParameters.pas
  54. 4 48
      CryptoLib/src/Math/EC/Endo/ClpGlvTypeBEndomorphism.pas
  55. 16 89
      CryptoLib/src/Math/EC/Endo/ClpGlvTypeBParameters.pas
  56. 131 0
      CryptoLib/src/Math/EC/Endo/ClpScalarSplitParameters.pas
  57. 0 101
      CryptoLib/src/Math/EC/Multiplier/ClpAbstractECMultiplier.pas
  58. 0 130
      CryptoLib/src/Math/EC/Multiplier/ClpFixedPointCombMultiplier.pas
  59. 0 219
      CryptoLib/src/Math/EC/Multiplier/ClpFixedPointUtilities.pas
  60. 0 106
      CryptoLib/src/Math/EC/Multiplier/ClpGlvMultiplier.pas
  61. 621 0
      CryptoLib/src/Math/EC/Multiplier/ClpMultipliers.pas
  62. 12 12
      CryptoLib/src/Math/EC/Multiplier/ClpValidityPrecompInfo.pas
  63. 0 191
      CryptoLib/src/Math/EC/Multiplier/ClpWNafL2RMultiplier.pas
  64. 101 22
      CryptoLib/src/Math/EC/Multiplier/ClpWNafPreCompInfo.pas
  65. 0 276
      CryptoLib/src/Math/EC/Multiplier/ClpWTauNafMultiplier.pas
  66. 23 23
      CryptoLib/src/Math/EC/Rfc8032/ClpEd25519.pas
  67. 59 3
      CryptoLib/src/Math/Raw/ClpNat.pas
  68. 19 14
      CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
  69. 693 682
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
  70. 41 40
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
  71. 0 2
      CryptoLib/src/Utils/Randoms/ClpAESPRNGRandom.pas

+ 43 - 38
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -32,7 +32,6 @@ uses
   ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
-  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -48,7 +47,6 @@ uses
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -69,10 +67,7 @@ uses
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.pas',
-  ClpAbstractECMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
-  ClpFixedPointCombMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
   ClpFixedPointPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
-  ClpFixedPointUtilities in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
   ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
@@ -107,14 +102,8 @@ uses
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
-  ClpGlvMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpGlvMultiplier.pas',
-  ClpIGlvMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIGlvMultiplier.pas',
-  ClpWTauNafMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafMultiplier.pas',
-  ClpIWTauNafMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafMultiplier.pas',
   ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.pas',
-  ClpWNafL2RMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas',
-  ClpIWNafL2RMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWNafL2RMultiplier.pas',
   ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
@@ -221,8 +210,8 @@ uses
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.pas',
-  ClpValidityPrecompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpValidityPrecompInfo.pas',
-  ClpIValidityPrecompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPrecompInfo.pas',
+  ClpValidityPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpValidityPreCompInfo.pas',
+  ClpIValidityPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPreCompInfo.pas',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
@@ -344,36 +333,52 @@ uses
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.pas',
-  ClpDHDomainParameters in '..\..\CryptoLib\src\Asn1\X9\ClpDHDomainParameters.pas',
-  ClpDHValidationParams in '..\..\CryptoLib\src\Asn1\X9\ClpDHValidationParams.pas',
-  ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
-  ClpDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHBasicAgreement.pas',
-  ClpDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas',
-  ClpDHKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyPairGenerator.pas',
-  ClpDHParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersGenerator.pas',
-  ClpDHKeyGeneratorHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyGeneratorHelper.pas',
   ClpDHParametersHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersHelper.pas',
-  ClpDHPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPrivateKeyParameters.pas',
-  ClpDHPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPublicKeyParameters.pas',
-  ClpDHKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyGenerationParameters.pas',
-  ClpDHKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyParameters.pas',
-  ClpDHValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHValidationParameters.pas',
+  ClpDHValidationParams in '..\..\CryptoLib\src\Asn1\X9\ClpDHValidationParams.pas',
+  ClpIDHValidationParams in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParams.pas',
+  ClpDHDomainParameters in '..\..\CryptoLib\src\Asn1\X9\ClpDHDomainParameters.pas',
+  ClpIDHDomainParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHDomainParameters.pas',
   ClpDHParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHParameters.pas',
-  ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
-  ClpIDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicAgreement.pas',
-  ClpIDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicKeyPairGenerator.pas',
-  ClpIDHKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyPairGenerator.pas',
-  ClpIDHPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPrivateKeyParameters.pas',
-  ClpIDHPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPublicKeyParameters.pas',
-  ClpIDHParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHParametersGenerator.pas',
-  ClpIDHKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGenerationParameters.pas',
   ClpIDHParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHParameters.pas',
-  ClpIDHKeyGeneratorHelper in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGeneratorHelper.pas',
-  ClpIDHKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyParameters.pas',
+  ClpDHValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHValidationParameters.pas',
   ClpIDHValidationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParameters.pas',
-  ClpIDHDomainParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHDomainParameters.pas',
-  ClpIDHValidationParams in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParams.pas',
+  ClpDHKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyParameters.pas',
+  ClpIDHKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyParameters.pas',
+  ClpDHKeyGeneratorHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyGeneratorHelper.pas',
+  ClpIDHKeyGeneratorHelper in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGeneratorHelper.pas',
+  ClpDHKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyGenerationParameters.pas',
+  ClpIDHKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGenerationParameters.pas',
+  ClpDHParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersGenerator.pas',
+  ClpIDHParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHParametersGenerator.pas',
+  ClpDHPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPublicKeyParameters.pas',
+  ClpIDHPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPublicKeyParameters.pas',
+  ClpDHPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPrivateKeyParameters.pas',
+  ClpIDHPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPrivateKeyParameters.pas',
+  ClpDHKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyPairGenerator.pas',
+  ClpIDHKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyPairGenerator.pas',
+  ClpIDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicKeyPairGenerator.pas',
+  ClpDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas',
+  ClpIDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicAgreement.pas',
+  ClpDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHBasicAgreement.pas',
+  ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
+  ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpAESPRNGRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpAESPRNGRandom.pas',
+  ClpCryptLibObjectIdentifiers in '..\..\CryptoLib\src\Asn1\CryptLib\ClpCryptLibObjectIdentifiers.pas',
+  ClpEndoPreCompInfo in '..\..\CryptoLib\src\Math\EC\Endo\ClpEndoPreCompInfo.pas',
+  ClpIEndoPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIEndoPreCompInfo.pas',
+  ClpScalarSplitParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpScalarSplitParameters.pas',
+  ClpIScalarSplitParameters in '..\..\CryptoLib\src\Interfaces\ClpIScalarSplitParameters.pas',
+  ClpScaleXNegateYPointMap in '..\..\CryptoLib\src\Math\EC\ClpScaleXNegateYPointMap.pas',
+  ClpIScaleXNegateYPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleXNegateYPointMap.pas',
+  ClpIScaleYNegateXPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleYNegateXPointMap.pas',
+  ClpScaleYNegateXPointMap in '..\..\CryptoLib\src\Math\EC\ClpScaleYNegateXPointMap.pas',
+  ClpGlvTypeAEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeAEndomorphism.pas',
+  ClpIGlvTypeAEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeAEndomorphism.pas',
+  ClpIGlvTypeAParameters in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeAParameters.pas',
+  ClpGlvTypeAParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeAParameters.pas',
+  ClpMultipliers in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpMultipliers.pas',
+  ClpIMultipliers in '..\..\CryptoLib\src\Interfaces\ClpIMultipliers.pas',
+  ClpECCompUtilities in '..\..\CryptoLib\src\Math\EC\ClpECCompUtilities.pas',
   UsageExamples in '..\src\UsageExamples.pas';
 
 begin

+ 18 - 13
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.TestInsight.dpr

@@ -42,7 +42,6 @@ uses
   ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
-  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -58,7 +57,6 @@ uses
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -79,10 +77,7 @@ uses
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.pas',
-  ClpAbstractECMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
-  ClpFixedPointCombMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
   ClpFixedPointPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
-  ClpFixedPointUtilities in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
   ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
@@ -117,14 +112,8 @@ uses
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
-  ClpGlvMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpGlvMultiplier.pas',
-  ClpIGlvMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIGlvMultiplier.pas',
-  ClpWTauNafMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafMultiplier.pas',
-  ClpIWTauNafMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafMultiplier.pas',
   ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.pas',
-  ClpWNafL2RMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas',
-  ClpIWNafL2RMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWNafL2RMultiplier.pas',
   ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
@@ -231,8 +220,8 @@ uses
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.pas',
-  ClpValidityPrecompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpValidityPrecompInfo.pas',
-  ClpIValidityPrecompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPrecompInfo.pas',
+  ClpValidityPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpValidityPreCompInfo.pas',
+  ClpIValidityPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPreCompInfo.pas',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
@@ -384,6 +373,22 @@ uses
   ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
   ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpAESPRNGRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpAESPRNGRandom.pas',
+  ClpCryptLibObjectIdentifiers in '..\..\CryptoLib\src\Asn1\CryptLib\ClpCryptLibObjectIdentifiers.pas',
+  ClpEndoPreCompInfo in '..\..\CryptoLib\src\Math\EC\Endo\ClpEndoPreCompInfo.pas',
+  ClpIEndoPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIEndoPreCompInfo.pas',
+  ClpScalarSplitParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpScalarSplitParameters.pas',
+  ClpIScalarSplitParameters in '..\..\CryptoLib\src\Interfaces\ClpIScalarSplitParameters.pas',
+  ClpScaleXNegateYPointMap in '..\..\CryptoLib\src\Math\EC\ClpScaleXNegateYPointMap.pas',
+  ClpIScaleXNegateYPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleXNegateYPointMap.pas',
+  ClpIScaleYNegateXPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleYNegateXPointMap.pas',
+  ClpScaleYNegateXPointMap in '..\..\CryptoLib\src\Math\EC\ClpScaleYNegateXPointMap.pas',
+  ClpGlvTypeAEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeAEndomorphism.pas',
+  ClpIGlvTypeAEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeAEndomorphism.pas',
+  ClpIGlvTypeAParameters in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeAParameters.pas',
+  ClpGlvTypeAParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeAParameters.pas',
+  ClpMultipliers in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpMultipliers.pas',
+  ClpIMultipliers in '..\..\CryptoLib\src\Interfaces\ClpIMultipliers.pas',
+  ClpECCompUtilities in '..\..\CryptoLib\src\Math\EC\ClpECCompUtilities.pas',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',

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

@@ -45,7 +45,6 @@ uses
   ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
-  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -61,7 +60,6 @@ uses
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -82,10 +80,7 @@ uses
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.pas',
-  ClpAbstractECMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
-  ClpFixedPointCombMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
   ClpFixedPointPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
-  ClpFixedPointUtilities in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
   ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
@@ -120,14 +115,8 @@ uses
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
-  ClpGlvMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpGlvMultiplier.pas',
-  ClpIGlvMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIGlvMultiplier.pas',
-  ClpWTauNafMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafMultiplier.pas',
-  ClpIWTauNafMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafMultiplier.pas',
   ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.pas',
-  ClpWNafL2RMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas',
-  ClpIWNafL2RMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWNafL2RMultiplier.pas',
   ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
@@ -234,8 +223,8 @@ uses
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.pas',
-  ClpValidityPrecompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpValidityPrecompInfo.pas',
-  ClpIValidityPrecompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPrecompInfo.pas',
+  ClpValidityPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpValidityPreCompInfo.pas',
+  ClpIValidityPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPreCompInfo.pas',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
@@ -387,6 +376,22 @@ uses
   ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
   ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpAESPRNGRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpAESPRNGRandom.pas',
+  ClpCryptLibObjectIdentifiers in '..\..\CryptoLib\src\Asn1\CryptLib\ClpCryptLibObjectIdentifiers.pas',
+  ClpEndoPreCompInfo in '..\..\CryptoLib\src\Math\EC\Endo\ClpEndoPreCompInfo.pas',
+  ClpIEndoPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIEndoPreCompInfo.pas',
+  ClpScalarSplitParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpScalarSplitParameters.pas',
+  ClpIScalarSplitParameters in '..\..\CryptoLib\src\Interfaces\ClpIScalarSplitParameters.pas',
+  ClpScaleXNegateYPointMap in '..\..\CryptoLib\src\Math\EC\ClpScaleXNegateYPointMap.pas',
+  ClpIScaleXNegateYPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleXNegateYPointMap.pas',
+  ClpIScaleYNegateXPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleYNegateXPointMap.pas',
+  ClpScaleYNegateXPointMap in '..\..\CryptoLib\src\Math\EC\ClpScaleYNegateXPointMap.pas',
+  ClpGlvTypeAEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeAEndomorphism.pas',
+  ClpIGlvTypeAEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeAEndomorphism.pas',
+  ClpIGlvTypeAParameters in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeAParameters.pas',
+  ClpGlvTypeAParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeAParameters.pas',
+  ClpMultipliers in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpMultipliers.pas',
+  ClpIMultipliers in '..\..\CryptoLib\src\Interfaces\ClpIMultipliers.pas',
+  ClpECCompUtilities in '..\..\CryptoLib\src\Math\EC\ClpECCompUtilities.pas',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',

+ 35 - 47
CryptoLib.Tests/src/Asn1/OIDTests.pas

@@ -43,15 +43,13 @@ type
   private
 
   var
-    Foid: string;
     Freq1, Freq2: TBytes;
 
     procedure DoRecodeCheck(const oid: String; const enc: TBytes);
     procedure DoValidOidCheck(const oid: String);
-    procedure DoInvalidOidCheck;
+    procedure DoInvalidOidCheck(const oid: String);
     procedure DoBranchCheck(const stem, branch: String);
     procedure DoOnCheck(const stem, test: String; expected: Boolean);
-    procedure DoConstructorMethod;
 
   protected
     procedure SetUp; override;
@@ -78,23 +76,18 @@ begin
     + branch);
 end;
 
-procedure TTestOID.DoConstructorMethod;
+procedure TTestOID.DoInvalidOidCheck(const oid: String);
 begin
-  TDerObjectIdentifier.Create(Foid);
-end;
-
-procedure TTestOID.DoInvalidOidCheck;
-var
-{$IFNDEF FPC}
-  Method: TTestMethod;
-{$ELSE}
-  Method: TRunMethod;
-{$ENDIF FPC}
-begin
-
-  Method := DoConstructorMethod;
-  CheckException(Method, EFormatCryptoLibException,
-    'Expected "EFormatCryptoLibException" But None Gotten');
+  try
+    TDerObjectIdentifier.Create(oid);
+    Fail(Format('failed to catch bad oid: %s', [oid]));
+
+  except
+    on e: EFormatCryptoLibException do
+    begin
+      // expected
+    end;
+  end;
 end;
 
 procedure TTestOID.DoOnCheck(const stem, test: String; expected: Boolean);
@@ -145,40 +138,35 @@ begin
   DoRecodeCheck('1.2.54.34359733987.17', Freq2);
 
   DoValidOidCheck('0.1');
+  DoValidOidCheck('1.0');
+  DoValidOidCheck('1.0.2');
+  DoValidOidCheck('1.0.20');
+  DoValidOidCheck('1.0.200');
   DoValidOidCheck
     ('1.1.127.32512.8323072.2130706432.545460846592.139637976727552.35747322042253312.9151314442816847872');
   DoValidOidCheck('1.2.123.12345678901.1.1.1');
 
   DoValidOidCheck('2.25.196556539987194312349856245628873852187.1');
 
-  Foid := '0';
-  DoInvalidOidCheck;
-  Foid := '1';
-  DoInvalidOidCheck;
-  Foid := '2';
-  DoInvalidOidCheck;
-  Foid := '3.1';
-  DoInvalidOidCheck;
-  Foid := '..1';
-  DoInvalidOidCheck;
-  Foid := '192.168.1.1';
-  DoInvalidOidCheck;
-  Foid := '.123452';
-  DoInvalidOidCheck;
-  Foid := '1.';
-  DoInvalidOidCheck;
-  Foid := '1.345.23.34..234';
-  DoInvalidOidCheck;
-  Foid := '1.345.23.34.234.';
-  DoInvalidOidCheck;
-  Foid := '.12.345.77.234';
-  DoInvalidOidCheck;
-  Foid := '.12.345.77.234.';
-  DoInvalidOidCheck;
-  Foid := '1.2.3.4.A.5';
-  DoInvalidOidCheck;
-  Foid := '1,2';
-  DoInvalidOidCheck;
+  DoInvalidOidCheck('0');
+  DoInvalidOidCheck('1');
+  DoInvalidOidCheck('2');
+  DoInvalidOidCheck('3.1');
+  DoInvalidOidCheck('0.01');
+  DoInvalidOidCheck('00.1');
+  DoInvalidOidCheck('1.00.2');
+  DoInvalidOidCheck('1.0.02');
+  DoInvalidOidCheck('1.2.00');
+  DoInvalidOidCheck('..1');
+  DoInvalidOidCheck('192.168.1.1');
+  DoInvalidOidCheck('.123452');
+  DoInvalidOidCheck('1.');
+  DoInvalidOidCheck('1.345.23.34..234');
+  DoInvalidOidCheck('1.345.23.34.234.');
+  DoInvalidOidCheck('.12.345.77.234');
+  DoInvalidOidCheck('.12.345.77.234.');
+  DoInvalidOidCheck('1.2.3.4.A.5');
+  DoInvalidOidCheck('1,2');
 
   DoBranchCheck('1.1', '2.2');
 

+ 2 - 2
CryptoLib.Tests/src/Math/EC/FixedPointTests.pas

@@ -37,8 +37,8 @@ uses
   ClpBigInteger,
   ClpECNamedCurveTable,
   ClpCustomNamedCurves,
-  ClpFixedPointCombMultiplier,
-  ClpIFixedPointCombMultiplier,
+  ClpMultipliers,
+  ClpIMultipliers,
   ClpECAlgorithms,
   ClpIX9ECParameters,
   ClpCryptoLibTypes,

+ 85 - 0
CryptoLib.Tests/src/Math/ECNRTests.pas

@@ -35,15 +35,23 @@ uses
   ClpIAsn1Objects,
   ClpIECC,
   ClpECC,
+  ClpIDigest,
   ClpECNRSigner,
   ClpIECNRSigner,
   ClpECDomainParameters,
   ClpIECDomainParameters,
+  ClpIECKeyGenerationParameters,
+  ClpECKeyGenerationParameters,
   ClpECPrivateKeyParameters,
   ClpIECPrivateKeyParameters,
   ClpECPublicKeyParameters,
   ClpIECPublicKeyParameters,
+  ClpECKeyPairGenerator,
+  ClpIECKeyPairGenerator,
   ClpISigner,
+  ClpIX9ECParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpECNamedCurveTable,
   ClpParametersWithRandom,
   ClpIParametersWithRandom,
   ClpSecureRandom,
@@ -51,8 +59,10 @@ uses
   ClpFixedSecureRandom,
   ClpSignerUtilities,
   ClpBigInteger,
+  ClpBigIntegers,
   ClpConverters,
   ClpCryptoLibTypes,
+  ClpDigestUtilities,
   CryptoLibTestBase;
 
 type
@@ -121,6 +131,8 @@ type
     /// </summary>
     procedure TestECNR521bitPrimeSHA512; // SecP521r1
 
+    procedure TestRange;
+
   end;
 
 implementation
@@ -462,6 +474,79 @@ begin
   DoCheckSignature(521, priKey, pubKey, sgr, k, &message, r, s);
 end;
 
+procedure TTestECNR.TestRange;
+var
+  myGenerator: IECKeyPairGenerator;
+  myRandom: ISecureRandom;
+  myCurve: String;
+  x9: IX9ECParameters;
+  myDomain: IECDomainParameters;
+  myParams: IECKeyGenerationParameters;
+  myPair: IAsymmetricCipherKeyPair;
+  myDigest: IDigest;
+  myArtifact, myMessage, msg: TCryptoLibByteArray;
+  signer: IECNRSigner;
+  order: TBigInteger;
+  sig: TCryptoLibGenericArray<TBigInteger>;
+begin
+  // Create the generator
+  myGenerator := TECKeyPairGenerator.Create();
+  myRandom := TSecureRandom.Create();
+  myCurve := 'brainpoolP192t1';
+
+  // Lookup the parameters
+  x9 := TECNamedCurveTable.GetByName(myCurve);
+
+  // Initialise the generator
+  myDomain := TECDomainParameters.Create(x9.curve, x9.G, x9.n, x9.H,
+    x9.GetSeed());
+  myParams := TECKeyGenerationParameters.Create(myDomain, myRandom);
+  myGenerator.Init(myParams);
+
+  // Create the key Pair
+  myPair := myGenerator.GenerateKeyPair();
+
+  // Create the digest and the output buffer
+  myDigest := TDigestUtilities.GetDigest('TIGER');
+  System.SetLength(myArtifact, myDigest.GetDigestSize);
+  myMessage := TConverters.ConvertStringToBytes
+    ('Hello there. How is life treating you?', TEncoding.ASCII);
+
+  myDigest.BlockUpdate(myMessage, 0, System.Length(myMessage));
+  myDigest.DoFinal(myArtifact, 0);
+
+  // Create signer
+  signer := TECNRSigner.Create();
+  signer.Init(true, myPair.Private);
+
+  try
+    signer.GenerateSignature(myArtifact);
+    Fail('out of range input not caught');
+  except
+    on e: EDataLengthCryptoLibException do
+    begin
+      CheckEquals(e.Message, 'Input Too Large For ECNR Key.');
+    end;
+
+  end;
+
+  //
+  // check upper bound
+  order := (myPair.Public as IECPublicKeyParameters).parameters.n;
+
+  signer.Init(true, myPair.Private);
+  msg := TBigIntegers.AsUnsignedByteArray(order.Subtract(TBigInteger.One));
+  sig := signer.GenerateSignature(msg);
+
+  signer.Init(false, myPair.getPublic());
+  if (not signer.VerifySignature(msg, sig[0], sig[1])) then
+  begin
+    Fail('ECNR failed 2');
+  end;
+
+  CheckTrue(AreEqual(msg, signer.getRecoveredMessage(sig[0], sig[1])));
+end;
+
 initialization
 
 // Register any test cases with the test runner

+ 167 - 11
CryptoLib.Tests/src/Math/ECPointTests.pas

@@ -26,6 +26,7 @@ interface
 uses
   Classes,
   SysUtils,
+  Math,
 {$IFDEF FPC}
   fpcunit,
   testregistry,
@@ -33,6 +34,7 @@ uses
   TestFramework,
 {$ENDIF FPC}
   Generics.Collections,
+  ClpBits,
   ClpCustomNamedCurves,
   ClpECNamedCurveTable,
   ClpCryptoLibTypes,
@@ -41,10 +43,14 @@ uses
   ClpBigInteger,
   ClpBigIntegers,
   ClpECAlgorithms,
+  ClpECCompUtilities,
   ClpIFiniteField,
   ClpIX9ECParameters,
+  ClpIX9ECC,
+  ClpX9ECC,
   ClpECC,
   ClpIECC,
+  ClpX9ECParameters,
   CryptoLibTestBase;
 
 type
@@ -73,7 +79,9 @@ type
   // */
   TF2m = class
 
-  public const
+  public
+
+    const
     // Irreducible polynomial for TPB z^4 + z + 1
     m = Int32(4);
 
@@ -200,6 +208,16 @@ type
     procedure ImplAddSubtractMultiplyTwiceEncodingTestAllCoords
       (const x9ECParameters: IX9ECParameters);
 
+    function SolveQuadraticEquation(const c: IECCurve;
+      const rhs: IECFieldElement): IECFieldElement;
+
+    function ConfigureBasepoint(const curve: IECCurve; const encoding: String)
+      : IX9ECPoint;
+
+    function ConfigureCurve(const curve: IECCurve): IECCurve;
+
+    function FromHex(const hex: String): TBigInteger;
+
   protected
     procedure SetUp; override;
     procedure TearDown; override;
@@ -245,6 +263,8 @@ type
     // */
     procedure TestAddSubtractMultiplyTwiceEncoding();
 
+    procedure TestExampleFpB0();
+
   end;
 
 implementation
@@ -289,11 +309,28 @@ begin
   CheckEquals(True, b.Equals(a), msg);
 end;
 
+function TTestECPoint.ConfigureBasepoint(const curve: IECCurve;
+  const encoding: String): IX9ECPoint;
+begin
+  result := TX9ECPoint.Create(curve, DecodeHex(encoding));
+  TWNafUtilities.ConfigureBasepoint(result.Point);
+end;
+
+function TTestECPoint.ConfigureCurve(const curve: IECCurve): IECCurve;
+begin
+  result := curve;
+end;
+
+function TTestECPoint.FromHex(const hex: String): TBigInteger;
+begin
+  result := TBigInteger.Create(1, DecodeHex(hex));
+end;
+
 procedure TTestECPoint.ImplAddSubtractMultiplyTwiceEncodingTest
   (const curve: IECCurve; const q: IECPoint; const n: TBigInteger);
 var
   infinity, p: IECPoint;
-  i: Int32;
+  i, logSize, rounds: Int32;
 begin
   // Get point at infinity on the curve
   infinity := curve.infinity;
@@ -301,10 +338,13 @@ begin
   ImplTestAddSubtract(q, infinity);
   ImplTestMultiply(q, n.BitLength);
   ImplTestMultiply(infinity, n.BitLength);
-  //
+
+  logSize := 32 - TBits.NumberOfLeadingZeros(curve.FieldSize - 1);
+  rounds := Max(2, Min(10, 32 - 3 * logSize));
+
   p := q;
   i := 0;
-  while i < 10 do
+  while i < rounds do
   begin
     ImplTestEncoding(p);
     p := p.Twice();
@@ -509,18 +549,47 @@ end;
 procedure TTestECPoint.ImplValidityTest(const c: IECCurve; const g: IECPoint);
 var
   h: TBigInteger;
-  order2, bad: IECPoint;
+  sqrtB, L, T, x, y: IECFieldElement;
+  order2, bad2, good2, order4, bad4_1, bad4_2, bad4_3, good4: IECPoint;
 begin
   CheckTrue(g.IsValid());
 
-  h := c.getCofactor();
-  if ((h.IsInitialized) and (h.CompareTo(TBigInteger.One) > 0)) then
+  if (TECAlgorithms.IsF2mCurve(c)) then
   begin
-    if (TECAlgorithms.IsF2mCurve(c)) then
+    h := c.Cofactor;
+    if (h.IsInitialized) then
     begin
-      order2 := c.CreatePoint(TBigInteger.Zero, c.b.Sqrt().ToBigInteger());
-      bad := g.Add(order2);
-      CheckFalse(bad.IsValid());
+      if (not h.TestBit(0)) then
+      begin
+        sqrtB := c.b.Sqrt();
+        order2 := c.CreatePoint(TBigInteger.Zero, sqrtB.ToBigInteger);
+        CheckTrue(order2.Twice().IsInfinity);
+        CheckFalse(order2.IsValid());
+        bad2 := g.Add(order2);
+        CheckFalse(bad2.IsValid());
+        good2 := bad2.Add(order2);
+        CheckTrue(good2.IsValid());
+
+        if (not h.TestBit(1)) then
+        begin
+          L := SolveQuadraticEquation(c, c.a);
+          CheckNotNull(L);
+          T := sqrtB;
+          x := T.Sqrt();
+          y := T.Add(x.Multiply(L));
+          order4 := c.CreatePoint(x.ToBigInteger(), y.ToBigInteger());
+          CheckTrue(order4.Twice().Equals(order2));
+          CheckFalse(order4.IsValid());
+          bad4_1 := g.Add(order4);
+          CheckFalse(bad4_1.IsValid());
+          bad4_2 := bad4_1.Add(order4);
+          CheckFalse(bad4_2.IsValid());
+          bad4_3 := bad4_2.Add(order4);
+          CheckFalse(bad4_3.IsValid());
+          good4 := bad4_3.Add(order4);
+          CheckTrue(good4.IsValid());
+        end;
+      end;
     end;
   end;
 end;
@@ -535,6 +604,51 @@ begin
   F2mInstance.CreatePoints;
 end;
 
+function TTestECPoint.SolveQuadraticEquation(const c: IECCurve;
+  const rhs: IECFieldElement): IECFieldElement;
+var
+  gamma, z, zeroElement, T, w, w2: IECFieldElement;
+  m, i: Int32;
+  rand: ISecureRandom;
+begin
+  if (rhs.IsZero) then
+  begin
+    result := rhs;
+    Exit;
+  end;
+
+  zeroElement := c.FromBigInteger(TBigInteger.Zero);
+  z := zeroElement;
+  gamma := z;
+
+  m := c.FieldSize;
+  rand := TSecureRandom.Create();
+
+  repeat
+    T := c.FromBigInteger(TBigInteger.Create(m, rand));
+    z := zeroElement;
+    w := rhs;
+    i := 1;
+
+    while i < m do
+    begin
+      w2 := w.Square();
+      z := z.Square().Add(w2.Multiply(T));
+      w := w2.Add(rhs);
+      System.Inc(i);
+    end;
+
+    if (not w.IsZero) then
+    begin
+      result := Nil;
+      Exit;
+    end;
+    gamma := z.Square().Add(z);
+  until (not gamma.IsZero);
+
+  result := z;
+end;
+
 procedure TTestECPoint.TearDown;
 begin
   inherited;
@@ -722,6 +836,48 @@ begin
   ImplTestTwice(F2mInstance.Fp);
 end;
 
+procedure TTestECPoint.TestExampleFpB0;
+var
+  p, a, b, n, h: TBigInteger;
+  s: TBytes;
+  curve: IECCurve;
+  g: IX9ECPoint;
+  x9: IX9ECParameters;
+begin
+  (*
+    * The supersingular curve y^2 := x^3 - 3.x (i.e. with 'B' = 0) from RFC 6508 2.1, with
+    * curve parameters from RFC 6509 Appendix A.
+  *)
+  p := FromHex('997ABB1F0A563FDA65C61198DAD0657A' +
+    '416C0CE19CB48261BE9AE358B3E01A2E' + 'F40AAB27E2FC0F1B228730D531A59CB0' +
+    'E791B39FF7C88A19356D27F4A666A6D0' + 'E26C6487326B4CD4512AC5CD65681CE1' +
+    'B6AFF4A831852A82A7CF3C521C3C09AA' + '9F94D6AF56971F1FFCE3E82389857DB0' +
+    '80C5DF10AC7ACE87666D807AFEA85FEB');
+  a := p.Subtract(TBigInteger.ValueOf(3));
+  b := TBigInteger.ValueOf(0);
+  s := Nil;
+  n := p.Add(TBigInteger.ValueOf(1)).ShiftRight(2);
+  h := TBigInteger.ValueOf(4);
+
+  curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
+
+  g := ConfigureBasepoint(curve, '04'
+    // Px
+    + '53FC09EE332C29AD0A7990053ED9B52A' + '2B1A2FD60AEC69C698B2F204B6FF7CBF' +
+    'B5EDB6C0F6CE2308AB10DB9030B09E10' + '43D5F22CDB9DFA55718BD9E7406CE890' +
+    '9760AF765DD5BCCB337C86548B72F2E1' + 'A702C3397A60DE74A7C1514DBA66910D' +
+    'D5CFB4CC80728D87EE9163A5B63F73EC' + '80EC46C4967E0979880DC8ABEAE63895'
+    // Py
+    + '0A8249063F6009F1F9F1F0533634A135' + 'D3E82016029906963D778D821E141178' +
+    'F5EA69F4654EC2B9E7F7F5E5F0DE55F6' + '6B598CCF9A140B2E416CFF0CA9E032B9' +
+    '70DAE117AD547C6CCAD696B5B7652FE0' + 'AC6F1E80164AA989492D979FC5A4D5F2' +
+    '13515AD7E9CB99A980BDAD5AD5BB4636' + 'ADB9B5706A67DCDE75573FD71BEF16D7');
+
+  x9 := TX9ECParameters.Create(curve, g, n, h, s);
+
+  ImplAddSubtractMultiplyTwiceEncodingTestAllCoords(x9);
+end;
+
 { TFp }
 
 constructor TFp.Create;

+ 21 - 28
CryptoLib/src/Asn1/ClpAsn1Objects.pas

@@ -4838,51 +4838,48 @@ end;
 class function TDerObjectIdentifier.IsValidBranchID(const branchID: String;
   start: Int32): Boolean;
 var
-  periodAllowed: Boolean;
-  Pos: Int32;
+  digitCount, Pos: Int32;
   ch: Char;
 begin
-  periodAllowed := False;
+  digitCount := 0;
 
   Pos := System.length(branchID) + 1;
   System.Dec(Pos);
+
   while (Pos >= start) do
   begin
     ch := branchID[Pos];
 
-    // TODO Leading zeroes?
-    // if (('0' <= ch) and (ch <= '9')) then
-    // begin
-    // periodAllowed := true;
-    // continue;
-    // end;
-
-    // TODO Leading zeroes?
-    if (CharInSet(ch, ['0' .. '9'])) then
-    begin
-      periodAllowed := True;
-      System.Dec(Pos);
-      continue;
-    end;
-
     if (ch = '.') then
     begin
-      if (not(periodAllowed)) then
+      if ((digitCount = 0) or ((digitCount > 1) and (branchID[Pos + 1] = '0')))
+      then
       begin
         result := False;
         Exit;
       end;
 
-      periodAllowed := False;
-      System.Dec(Pos);
-      continue;
+      digitCount := 0;
+    end
+    else if (CharInSet(ch, ['0' .. '9'])) then
+    begin
+      System.Inc(digitCount);
+    end
+    else
+    begin
+      result := False;
+      Exit;
     end;
+    System.Dec(Pos);
+  end;
 
+  if ((digitCount = 0) or ((digitCount > 1) and (branchID[Pos + 1] = '0'))) then
+  begin
     result := False;
     Exit;
   end;
 
-  result := periodAllowed;
+  result := True;
 end;
 
 class function TDerObjectIdentifier.IsValidIdentifier(const identifier
@@ -4897,11 +4894,7 @@ begin
   end;
 
   first := identifier[1];
-  // if ((first < '0') or (first > '2')) then
-  // begin
-  // result := false;
-  // Exit;
-  // end;
+
   if (not CharInSet(first, ['0' .. '2'])) then
   begin
     result := False;

+ 90 - 0
CryptoLib/src/Asn1/CryptLib/ClpCryptLibObjectIdentifiers.pas

@@ -0,0 +1,90 @@
+{ *********************************************************************************** }
+{ *                              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 ClpCryptLibObjectIdentifiers;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpAsn1Objects,
+  ClpIAsn1Objects;
+
+type
+  TCryptLibObjectIdentifiers = class abstract(TObject)
+
+  strict private
+
+  class var
+
+    FIsBooted: Boolean;
+    FCryptlib, FEcc, FCurvey25519: IDerObjectIdentifier;
+
+    class constructor CryptLibObjectIdentifiers();
+  private
+    class function GetCryptlib: IDerObjectIdentifier; static; inline;
+    class function GetEcc: IDerObjectIdentifier; static; inline;
+    class function GetCurvey25519: IDerObjectIdentifier; static; inline;
+
+  public
+
+    class property Cryptlib: IDerObjectIdentifier read GetCryptlib;
+    class property Ecc: IDerObjectIdentifier read GetEcc;
+    class property Curvey25519: IDerObjectIdentifier read GetCurvey25519;
+
+    class procedure Boot(); static;
+  end;
+
+implementation
+
+{ TCryptLibObjectIdentifiers }
+
+class procedure TCryptLibObjectIdentifiers.Boot;
+begin
+  if not FIsBooted then
+  begin
+    FCryptlib := TDerObjectIdentifier.Create('1.3.6.1.4.1.3029');
+
+    FEcc := Cryptlib.branch('1').branch('5');
+    FCurvey25519 := Ecc.branch('1');
+
+    FIsBooted := True;
+  end;
+end;
+
+class constructor TCryptLibObjectIdentifiers.CryptLibObjectIdentifiers;
+begin
+  TCryptLibObjectIdentifiers.Boot();
+end;
+
+class function TCryptLibObjectIdentifiers.GetCryptlib: IDerObjectIdentifier;
+begin
+  result := FCryptlib;
+end;
+
+class function TCryptLibObjectIdentifiers.GetEcc: IDerObjectIdentifier;
+begin
+  result := FEcc;
+end;
+
+class function TCryptLibObjectIdentifiers.GetCurvey25519: IDerObjectIdentifier;
+begin
+  result := FCurvey25519;
+end;
+
+end.

+ 184 - 203
CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas

@@ -29,6 +29,7 @@ uses
   ClpIGlvTypeBEndomorphism,
   ClpSecObjectIdentifiers,
   ClpCryptoLibTypes,
+  ClpECCompUtilities,
   ClpBigInteger,
   ClpECC,
   ClpIECC,
@@ -36,6 +37,8 @@ uses
   ClpIX9ECC,
   ClpIAsn1Objects,
   ClpGlvTypeBEndomorphism,
+  ClpIScalarSplitParameters,
+  ClpScalarSplitParameters,
   ClpX9ECParameters,
   ClpIX9ECParameters,
   ClpX9ECParametersHolder,
@@ -63,6 +66,9 @@ type
       const p: IGlvTypeBParameters): IECCurve; static; inline;
     class function FromHex(const Hex: String): TBigInteger; static; inline;
 
+    class function ConfigureBasepoint(const curve: IECCurve;
+      const encoding: String): IX9ECPoint; static;
+
     class procedure Boot(); static;
     class constructor CreateSecNamedCurves();
     class destructor DestroySecNamedCurves();
@@ -347,7 +353,7 @@ type
 
     strict private
     const
-      Fm = Int32(113);
+      M = Int32(113);
       Fk = Int32(9);
 
     strict protected
@@ -368,7 +374,7 @@ type
 
     strict private
     const
-      Fm = Int32(113);
+      M = Int32(113);
       Fk = Int32(9);
 
     strict protected
@@ -389,10 +395,10 @@ type
 
     strict private
     const
-      Fm = Int32(131);
-      Fk1 = Int32(2);
-      Fk2 = Int32(3);
-      Fk3 = Int32(8);
+      M = Int32(131);
+      K1 = Int32(2);
+      K2 = Int32(3);
+      K3 = Int32(8);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -412,10 +418,10 @@ type
 
     strict private
     const
-      Fm = Int32(131);
-      Fk1 = Int32(2);
-      Fk2 = Int32(3);
-      Fk3 = Int32(8);
+      M = Int32(131);
+      K1 = Int32(2);
+      K2 = Int32(3);
+      K3 = Int32(8);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -435,10 +441,10 @@ type
 
     strict private
     const
-      Fm = Int32(163);
-      Fk1 = Int32(3);
-      Fk2 = Int32(6);
-      Fk3 = Int32(7);
+      M = Int32(163);
+      K1 = Int32(3);
+      K2 = Int32(6);
+      K3 = Int32(7);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -458,10 +464,10 @@ type
 
     strict private
     const
-      Fm = Int32(163);
-      Fk1 = Int32(3);
-      Fk2 = Int32(6);
-      Fk3 = Int32(7);
+      M = Int32(163);
+      K1 = Int32(3);
+      K2 = Int32(6);
+      K3 = Int32(7);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -481,10 +487,10 @@ type
 
     strict private
     const
-      Fm = Int32(163);
-      Fk1 = Int32(3);
-      Fk2 = Int32(6);
-      Fk3 = Int32(7);
+      M = Int32(163);
+      K1 = Int32(3);
+      K2 = Int32(6);
+      K3 = Int32(7);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -504,7 +510,7 @@ type
 
     strict private
     const
-      Fm = Int32(193);
+      M = Int32(193);
       Fk = Int32(15);
 
     strict protected
@@ -525,7 +531,7 @@ type
 
     strict private
     const
-      Fm = Int32(193);
+      M = Int32(193);
       Fk = Int32(15);
 
     strict protected
@@ -546,7 +552,7 @@ type
 
     strict private
     const
-      Fm = Int32(233);
+      M = Int32(233);
       Fk = Int32(74);
 
     strict protected
@@ -567,7 +573,7 @@ type
 
     strict private
     const
-      Fm = Int32(233);
+      M = Int32(233);
       Fk = Int32(74);
 
     strict protected
@@ -588,7 +594,7 @@ type
 
     strict private
     const
-      Fm = Int32(239);
+      M = Int32(239);
       Fk = Int32(158);
 
     strict protected
@@ -609,10 +615,10 @@ type
 
     strict private
     const
-      Fm = Int32(283);
-      Fk1 = Int32(5);
-      Fk2 = Int32(7);
-      Fk3 = Int32(12);
+      M = Int32(283);
+      K1 = Int32(5);
+      K2 = Int32(7);
+      K3 = Int32(12);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -632,10 +638,10 @@ type
 
     strict private
     const
-      Fm = Int32(283);
-      Fk1 = Int32(5);
-      Fk2 = Int32(7);
-      Fk3 = Int32(12);
+      M = Int32(283);
+      K1 = Int32(5);
+      K2 = Int32(7);
+      K3 = Int32(12);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -655,7 +661,7 @@ type
 
     strict private
     const
-      Fm = Int32(409);
+      M = Int32(409);
       Fk = Int32(87);
 
     strict protected
@@ -676,7 +682,7 @@ type
 
     strict private
     const
-      Fm = Int32(409);
+      M = Int32(409);
       Fk = Int32(87);
 
     strict protected
@@ -697,10 +703,10 @@ type
 
     strict private
     const
-      Fm = Int32(571);
-      Fk1 = Int32(2);
-      Fk2 = Int32(5);
-      Fk3 = Int32(10);
+      M = Int32(571);
+      K1 = Int32(2);
+      K2 = Int32(5);
+      K3 = Int32(10);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -720,10 +726,10 @@ type
 
     strict private
     const
-      Fm = Int32(571);
-      Fk1 = Int32(2);
-      Fk2 = Int32(5);
-      Fk3 = Int32(10);
+      M = Int32(571);
+      K1 = Int32(2);
+      K2 = Int32(5);
+      K3 = Int32(10);
 
     strict protected
       function CreateParameters(): IX9ECParameters; override;
@@ -739,6 +745,13 @@ implementation
 
 { TSecNamedCurves }
 
+class function TSecNamedCurves.ConfigureBasepoint(const curve: IECCurve;
+  const encoding: String): IX9ECPoint;
+begin
+  result := TX9ECPoint.Create(curve, THex.Decode(encoding));
+  TWnafUtilities.ConfigureBasepoint(result.Point);
+end;
+
 class procedure TSecNamedCurves.DefineCurve(const name: String;
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
 begin
@@ -922,9 +935,8 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '09487239995A5EE76B55F9C2F098' +
-    'A89CE5AF8724C0A23E0E0FF77500'));
+  G := ConfigureBasepoint(curve,
+    '0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -952,9 +964,8 @@ begin
   h := TBigInteger.ValueOf(4);
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '4BA30AB5E892B4E1649DD0928643' +
-    'ADCD46F5882E3747DEF36E956E97'));
+  G := ConfigureBasepoint(curve,
+    '044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -982,9 +993,8 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '161FF7528B899B2D0C28607CA52C5B86' +
-    'CF5AC8395BAFEB13C02DA292DDED7A83'));
+  G := ConfigureBasepoint(curve,
+    '04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1012,9 +1022,8 @@ begin
   h := TBigInteger.ValueOf(4);
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '7B6AA5D85E572983E6FB32A7CDEBC140' +
-    '27B6916A894D3AEE7106FE805FC34B44'));
+  G := ConfigureBasepoint(curve,
+    '047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1045,19 +1054,20 @@ begin
   glv := TGlvTypeBParameters.Create
     (TBigInteger.Create('9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a', 16),
     TBigInteger.Create('c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('9162fbe73984472a0a9e', 16),
     TBigInteger.Create('-96341f1138933bc2f505', 16)),
-    TCryptoLibGenericArray<TBigInteger>.Create
-    (TBigInteger.Create('127971af8721782ecffa3', 16),
-    TBigInteger.Create('9162fbe73984472a0a9e', 16)),
-    TBigInteger.Create('9162fbe73984472a0a9d0590', 16),
-    TBigInteger.Create('96341f1138933bc2f503fd44', 16), 176);
+
+    TCryptoLibGenericArray<TBigInteger>.Create(TBigInteger.Create
+    ('127971af8721782ecffa3', 16), TBigInteger.Create('9162fbe73984472a0a9e',
+    16)), TBigInteger.Create('9162fbe73984472a0a9d0590', 16),
+    TBigInteger.Create('96341f1138933bc2f503fd44', 16), 176)
+    as IScalarSplitParameters);
 
   curve := ConfigureCurveGlv(TFpCurve.Create(p, a, b, n, h) as IFpCurve, glv);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '3B4C382CE37AA192A4019E763036F4F5DD4D7EBB' +
-    '938CF935318FDCED6BC28286531733C3F03C4FEE'));
+  G := ConfigureBasepoint(curve,
+    '043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1085,9 +1095,8 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '4A96B5688EF573284664698968C38BB913CBFC82' +
-    '23A628553168947D59DCC912042351377AC5FB32'));
+  G := ConfigureBasepoint(curve,
+    '044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1115,9 +1124,8 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '52DCB034293A117E1F4FF11B30F7199D3144CE6D' +
-    'FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E'));
+  G := ConfigureBasepoint(curve,
+    '0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1148,19 +1156,20 @@ begin
   glv := TGlvTypeBParameters.Create
     (TBigInteger.Create('bb85691939b869c1d087f601554b96b80cb4f55b35f433c2', 16),
     TBigInteger.Create('3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('71169be7330b3038edb025f1', 16),
     TBigInteger.Create('-b3fb3400dec5c4adceb8655c', 16)),
-    TCryptoLibGenericArray<TBigInteger>.Create
-    (TBigInteger.Create('12511cfe811d0f4e6bc688b4d', 16),
+    TCryptoLibGenericArray<TBigInteger>.Create(TBigInteger.Create
+    ('12511cfe811d0f4e6bc688b4d', 16),
     TBigInteger.Create('71169be7330b3038edb025f1', 16)),
     TBigInteger.Create('71169be7330b3038edb025f1d0f9', 16),
-    TBigInteger.Create('b3fb3400dec5c4adceb8655d4c94', 16), 208);
+    TBigInteger.Create('b3fb3400dec5c4adceb8655d4c94', 16), 208)
+    as IScalarSplitParameters);
 
   curve := ConfigureCurveGlv(TFpCurve.Create(p, a, b, n, h) as IFpCurve, glv);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + 'DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D' +
-    '9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D'));
+  G := ConfigureBasepoint(curve,
+    '04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1188,9 +1197,8 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012' +
-    '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811'));
+  G := ConfigureBasepoint(curve,
+    '04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1223,20 +1231,19 @@ begin
     ('fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768', 16),
     TBigInteger.Create
     ('60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('6b8cf07d4ca75c88957d9d670591', 16),
     TBigInteger.Create('-b8adf1378a6eb73409fa6c9c637d', 16)),
-    TCryptoLibGenericArray<TBigInteger>.Create
-    (TBigInteger.Create('1243ae1b4d71613bc9f780a03690e', 16),
+    TCryptoLibGenericArray<TBigInteger>.Create(TBigInteger.Create
+    ('1243ae1b4d71613bc9f780a03690e', 16),
     TBigInteger.Create('6b8cf07d4ca75c88957d9d670591', 16)),
     TBigInteger.Create('6b8cf07d4ca75c88957d9d67059037a4', 16),
-    TBigInteger.Create('b8adf1378a6eb73409fa6c9c637ba7f5', 16), 240);
+    TBigInteger.Create('b8adf1378a6eb73409fa6c9c637ba7f5', 16), 240)
+    as IScalarSplitParameters);
 
   curve := ConfigureCurveGlv(TFpCurve.Create(p, a, b, n, h) as IFpCurve, glv);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    'A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C' +
-    '7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5'));
+  G := ConfigureBasepoint(curve,
+    '04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1264,10 +1271,8 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    'B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21' +
-    'BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34'));
+  G := ConfigureBasepoint(curve,
+    '04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1302,20 +1307,20 @@ begin
     ('7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', 16),
     TBigInteger.Create
     ('5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16),
     TBigInteger.Create('-e4437ed6010e88286f547fa90abfe4c3', 16)),
-    TCryptoLibGenericArray<TBigInteger>.Create
-    (TBigInteger.Create('114ca50f7a8e2f3f657c1108d9d44cfd8', 16),
+    TCryptoLibGenericArray<TBigInteger>.Create(TBigInteger.Create
+    ('114ca50f7a8e2f3f657c1108d9d44cfd8', 16),
     TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16)),
     TBigInteger.Create('3086d221a7d46bcde86c90e49284eb153dab', 16),
-    TBigInteger.Create('e4437ed6010e88286f547fa90abfe4c42212', 16), 272);
+    TBigInteger.Create('e4437ed6010e88286f547fa90abfe4c42212', 16), 272)
+    as IScalarSplitParameters);
 
   curve := ConfigureCurveGlv(TFpCurve.Create(p, a, b, n, h) as IFpCurve, glv);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798' +
-    '483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8'));
+  G := ConfigureBasepoint(curve,
+    '0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1347,10 +1352,8 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296' +
-    '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5'));
+  G := ConfigureBasepoint(curve,
+    '046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1382,11 +1385,9 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7'
-    + '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F')
-    );
+  G := ConfigureBasepoint(curve,
+    '04' + 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7'
+    + '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1418,11 +1419,9 @@ begin
   h := TBigInteger.One;
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66'
-    + '011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650')
-    );
+  G := ConfigureBasepoint(curve,
+    '04' + '00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66'
+    + '011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1447,10 +1446,9 @@ begin
   n := FromHex('0100000000000000D9CCEC8A39E56F');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '009D73616F35F4AB1407D73562C10F' +
-    '00A52830277958EE84D1315ED31886'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1475,10 +1473,9 @@ begin
   n := FromHex('010000000000000108789B2496AF93');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '01A57A6A7B26CA5EF52FCDB8164797' +
-    '00B3ADC94ED1FE674C06E695BABA1D'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1503,10 +1500,10 @@ begin
   n := FromHex('0400000000000000023123953A9464B54D');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '0081BAF91FDF9833C40F9C181343638399' +
-    '078C6E7EA38C001F73C8134B1B4EF9E150'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1531,10 +1528,10 @@ begin
   n := FromHex('0400000000000000016954A233049BA98F');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '0356DCD8F2F95031AD652D23951BB366A8' +
-    '0648F06D867940A5366D9E265DE9EB240F'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1559,10 +1556,10 @@ begin
   n := FromHex('04000000000000000000020108A2E0CC0D99F8A5EF');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8' +
-    '0289070FB05D38FF58321F2E800536D538CCDAA3D9'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1587,10 +1584,10 @@ begin
   n := FromHex('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '0369979697AB43897789566789567F787A7876A654' +
-    '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1615,10 +1612,10 @@ begin
   n := FromHex('040000000000000000000292FE77E70C12A4234C33');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '03F0EBA16286A2D57EA0991168D4994637E8343E36' +
-    '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1643,10 +1640,9 @@ begin
   n := FromHex('01000000000000000000000000C7F34A778F443ACC920EBA49');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1' +
-    '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1671,10 +1667,9 @@ begin
   n := FromHex('010000000000000000000000015AAB561B005413CCD4EE99D5');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' + '00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F' +
-    '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1699,11 +1694,9 @@ begin
   n := FromHex('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF');
   h := TBigInteger.ValueOf(4);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126' +
-    '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1728,11 +1721,9 @@ begin
   n := FromHex('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B' +
-    '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1757,11 +1748,9 @@ begin
   n := FromHex('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5');
   h := TBigInteger.ValueOf(4);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC' +
-    '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA'));
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1787,12 +1776,11 @@ begin
     ('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61');
   h := TBigInteger.ValueOf(4);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836' +
-    '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259')
-    );
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04' + '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836'
+    + '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1819,12 +1807,11 @@ begin
     ('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053' +
-    '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4')
-    );
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04' + '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053'
+    + '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1850,12 +1837,10 @@ begin
     ('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF');
   h := TBigInteger.ValueOf(4);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746'
-    + '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B')
-    );
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04' + '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746'
+    + '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1882,12 +1867,10 @@ begin
     ('010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7'
-    + '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706')
-    );
+  curve := ConfigureCurve(TF2mCurve.Create(M, Fk, a, b, n, h) as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04' + '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7'
+    + '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1913,12 +1896,11 @@ begin
     ('020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001');
   h := TBigInteger.ValueOf(4);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972'
-    + '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3')
-    );
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04' + '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972'
+    + '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
@@ -1945,12 +1927,11 @@ begin
     ('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47');
   h := TBigInteger.ValueOf(2);
 
-  curve := TF2mCurve.Create(Fm, Fk1, Fk2, Fk3, a, b, n, h);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19'
-    + '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B')
-    );
+  curve := ConfigureCurve(TF2mCurve.Create(M, K1, K2, K3, a, b, n, h)
+    as IF2mCurve);
+  G := ConfigureBasepoint(curve,
+    '04' + '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19'
+    + '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B');
 
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;

+ 78 - 67
CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTNamedCurves.pas

@@ -28,6 +28,7 @@ uses
   ClpTeleTrusTObjectIdentifiers,
   ClpCryptoLibTypes,
   ClpBigInteger,
+  ClpECCompUtilities,
   ClpECC,
   ClpIECC,
   ClpX9ECC,
@@ -61,6 +62,9 @@ type
     class function ConfigureCurve(const curve: IECCurve): IECCurve;
       static; inline;
 
+    class function ConfigureBasepoint(const curve: IECCurve;
+      const encoding: String): IX9ECPoint; static;
+
     class procedure Boot(); static;
     class constructor CreateTeleTrusTNamedCurves();
     class destructor DestroyTeleTrusTNamedCurves();
@@ -325,6 +329,13 @@ implementation
 
 { TeleTrusTNamedCurves }
 
+class function TTeleTrusTNamedCurves.ConfigureBasepoint(const curve: IECCurve;
+  const encoding: String): IX9ECPoint;
+begin
+  result := TX9ECPoint.Create(curve, THex.Decode(encoding));
+  TWnafUtilities.ConfigureBasepoint(result.Point);
+end;
+
 class function TTeleTrusTNamedCurves.ConfigureCurve(const curve: IECCurve)
   : IECCurve;
 begin
@@ -448,6 +459,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP160r1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create('E95E4A5F737059DC60DF5991D45029409E60FC09', 16);
   h := TBigInteger.Create('01', 16);
@@ -459,11 +471,10 @@ begin
     TBigInteger.Create('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16), // b
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321')
-    ) as IX9ECPoint, // G
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP160r1Holder.Instance
@@ -479,6 +490,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP160t1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create('E95E4A5F737059DC60DF5991D45029409E60FC09', 16);
   h := TBigInteger.Create('01', 16);
@@ -490,11 +502,10 @@ begin
     TBigInteger.Create('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16), // b'
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD')
-    ) as IX9ECPoint, // G'
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP160t1Holder.Instance
@@ -510,6 +521,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP192r1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16);
@@ -524,11 +536,10 @@ begin
     // b
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F')
-    ) as IX9ECPoint, // G
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP192r1Holder.Instance
@@ -544,6 +555,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP192t1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16);
@@ -558,11 +570,10 @@ begin
     // b'
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9')
-    ) as IX9ECPoint, // G'
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP192t1Holder.Instance
@@ -578,6 +589,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP224r1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16);
@@ -594,11 +606,10 @@ begin
     // b
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD')
-    ) as IX9ECPoint, // G
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP224r1Holder.Instance
@@ -614,6 +625,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP224t1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16);
@@ -630,11 +642,10 @@ begin
     // b'
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C')
-    ) as IX9ECPoint, // G'
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP224t1Holder.Instance
@@ -650,6 +661,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP256r1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16);
@@ -667,11 +679,10 @@ begin
     // b
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997')
-    ) as IX9ECPoint, // G
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP256r1Holder.Instance
@@ -687,6 +698,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP256t1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16);
@@ -704,11 +716,10 @@ begin
     // b'
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE')
-    ) as IX9ECPoint, // G'
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP256t1Holder.Instance
@@ -765,6 +776,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP320t1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311',
@@ -786,11 +798,10 @@ begin
     // b'
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3')
-    ) as IX9ECPoint, // G'
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP320t1Holder.Instance
@@ -806,6 +817,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP384r1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
@@ -827,11 +839,10 @@ begin
     // b
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315')
-    ) as IX9ECPoint, // G
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP384r1Holder.Instance
@@ -847,6 +858,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP384t1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
@@ -868,11 +880,10 @@ begin
     // b'
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928')
-    ) as IX9ECPoint, // G'
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP384t1Holder.Instance
@@ -888,6 +899,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP512r1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
@@ -909,12 +921,11 @@ begin
     // b
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97'
-    + 'D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892')
-    ) as IX9ECPoint, // G
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF' +
+    '3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP512r1Holder.Instance
@@ -930,6 +941,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP512t1Holder.CreateParameters
 var
   n, h: TBigInteger;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
   n := TBigInteger.Create
     ('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
@@ -951,12 +963,11 @@ begin
     // b'
     n, h) as IFpCurve);
 
-  result := TX9ECParameters.Create(curve, TX9ECPoint.Create(curve,
-    THex.Decode
-    ('04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D'
-    + '6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332')
-    ) as IX9ECPoint, // G'
-    n, h);
+  G := ConfigureBasepoint(curve,
+    '04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5'
+    + 'B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332');
+
+  result := TX9ECParameters.Create(curve, G, n, h);
 end;
 
 class function TTeleTrusTNamedCurves.TBrainpoolP512t1Holder.Instance

+ 48 - 42
CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas

@@ -28,9 +28,11 @@ uses
   ClpGlvTypeBParameters,
   ClpIGlvTypeBEndomorphism,
   ClpSecObjectIdentifiers,
+  ClpCryptLibObjectIdentifiers,
   ClpCryptoLibTypes,
   ClpBigInteger,
   ClpECC,
+  ClpECCompUtilities,
   ClpSecP256K1Custom,
   ClpISecP256K1Custom,
   ClpSecP256R1Custom,
@@ -47,6 +49,8 @@ uses
   ClpX9ECC,
   ClpIX9ECC,
   ClpIAsn1Objects,
+  ClpScalarSplitParameters,
+  ClpIScalarSplitParameters,
   ClpGlvTypeBEndomorphism,
   ClpX9ECParameters,
   ClpIX9ECParameters,
@@ -69,8 +73,8 @@ type
 
     class function GetNames: TCryptoLibStringArray; static; inline;
 
-    class procedure DefineCurve(const name: String;
-      const holder: IX9ECParametersHolder); static; inline;
+    // class procedure DefineCurve(const name: String;
+    // const holder: IX9ECParametersHolder); static; inline;
 
     class procedure DefineCurveWithOid(const name: String;
       const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
@@ -84,6 +88,9 @@ type
     class function ConfigureCurveGlv(const c: IECCurve;
       const p: IGlvTypeBParameters): IECCurve; static; inline;
 
+    class function ConfigureBasepoint(const curve: IECCurve;
+      const encoding: String): IX9ECPoint; static;
+
     class procedure Boot(); static;
     class constructor CreateCustomNamedCurves();
     class destructor DestroyCustomNamedCurves();
@@ -220,17 +227,24 @@ implementation
 
 { TCustomNamedCurves }
 
-class procedure TCustomNamedCurves.DefineCurve(const name: String;
-  const holder: IX9ECParametersHolder);
-var
-  LName: string;
+class function TCustomNamedCurves.ConfigureBasepoint(const curve: IECCurve;
+  const encoding: String): IX9ECPoint;
 begin
-  LName := name;
-  Fnames.Add(LName);
-  LName := UpperCase(LName);
-  FnameToCurve.Add(LName, holder);
+  result := TX9ECPoint.Create(curve, THex.Decode(encoding));
+  TWnafUtilities.ConfigureBasepoint(result.Point);
 end;
 
+// class procedure TCustomNamedCurves.DefineCurve(const name: String;
+// const holder: IX9ECParametersHolder);
+// var
+// LName: string;
+// begin
+// LName := name;
+// Fnames.Add(LName);
+// LName := UpperCase(LName);
+// FnameToCurve.Add(LName, holder);
+// end;
+
 class procedure TCustomNamedCurves.DefineCurveWithOid(const name: String;
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
 var
@@ -353,7 +367,8 @@ begin
 
   Fnames := TList<String>.Create();
 
-  DefineCurve('curve25519', TCurve25519Holder.Instance);
+  DefineCurveWithOid('curve25519', TCryptlibObjectIdentifiers.Curvey25519,
+    TCurve25519Holder.Instance);
 
   DefineCurveWithOid('secp256k1', TSecObjectIdentifiers.SecP256k1,
     TSecP256K1Holder.Instance);
@@ -397,10 +412,8 @@ begin
     *
     * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
     * }
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A' +
-    '20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9'));
+  G := ConfigureBasepoint(curve,
+    '042AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9');
 
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
@@ -426,19 +439,19 @@ begin
     ('7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', 16),
     TBigInteger.Create
     ('5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16),
     TBigInteger.Create('-e4437ed6010e88286f547fa90abfe4c3', 16)),
-    TCryptoLibGenericArray<TBigInteger>.Create
-    (TBigInteger.Create('114ca50f7a8e2f3f657c1108d9d44cfd8', 16),
+    TCryptoLibGenericArray<TBigInteger>.Create(TBigInteger.Create
+    ('114ca50f7a8e2f3f657c1108d9d44cfd8', 16),
     TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16)),
     TBigInteger.Create('3086d221a7d46bcde86c90e49284eb153dab', 16),
-    TBigInteger.Create('e4437ed6010e88286f547fa90abfe4c42212', 16), 272);
+    TBigInteger.Create('e4437ed6010e88286f547fa90abfe4c42212', 16), 272)
+    as IScalarSplitParameters);
   curve := ConfigureCurveGlv(TSecP256K1Curve.Create() as ISecP256K1Curve, glv);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798' +
-    '483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8'));
+  G := ConfigureBasepoint(curve,
+    '0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8');
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 
@@ -458,11 +471,9 @@ var
 begin
   S := THex.Decode('A335926AA319A27A1D00896A6773A4827ACDAC73');
   curve := ConfigureCurve(TSecP384R1Curve.Create() as ISecP384R1Curve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7'
-    + '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F')
-    );
+  G := ConfigureBasepoint(curve,
+    '04' + 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7'
+    + '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F');
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 
@@ -482,11 +493,9 @@ var
 begin
   S := THex.Decode('D09E8800291CB85396CC6717393284AAA0DA64BA');
   curve := ConfigureCurve(TSecP521R1Curve.Create() as ISecP521R1Curve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66'
-    + '011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650')
-    );
+  G := ConfigureBasepoint(curve,
+    '04' + '00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66'
+    + '011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650');
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 
@@ -506,11 +515,9 @@ var
 begin
   S := Nil;
   curve := ConfigureCurve(TSecT283K1Curve.Create() as ISecT283K1Curve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836' +
-    '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259')
-    );
+  G := ConfigureBasepoint(curve,
+    '04' + '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836'
+    + '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259');
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 
@@ -530,10 +537,9 @@ var
 begin
   S := THex.Decode('C49D360886E704936A6678E1139D26B7819F7E90');
   curve := ConfigureCurve(TSecP256R1Curve.Create() as ISecP256R1Curve);
-  G := TX9ECPoint.Create(curve,
-    THex.Decode('04' +
-    '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296' +
-    '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5'));
+  G := ConfigureBasepoint(curve,
+    '046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5');
+
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 

+ 1 - 1
CryptoLib/src/Crypto/Generators/ClpDHKeyGeneratorHelper.pas

@@ -27,7 +27,7 @@ uses
   ClpBits,
   ClpBigInteger,
   ClpBigIntegers,
-  ClpECAlgorithms,
+  ClpECCompUtilities,
   ClpIDHParameters,
   ClpIDHKeyGeneratorHelper;
 

+ 1 - 1
CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas

@@ -25,7 +25,7 @@ uses
   ClpISecureRandom,
   ClpBigInteger,
   ClpBigIntegers,
-  ClpECAlgorithms,
+  ClpECCompUtilities,
   ClpBits,
   ClpCryptoLibTypes;
 

+ 1 - 1
CryptoLib/src/Crypto/Generators/ClpDsaKeyPairGenerator.pas

@@ -37,7 +37,7 @@ uses
   ClpBits,
   ClpBigInteger,
   ClpBigIntegers,
-  ClpECAlgorithms,
+  ClpECCompUtilities,
   ClpCryptoLibTypes;
 
 resourcestring

+ 3 - 3
CryptoLib/src/Crypto/Generators/ClpECKeyPairGenerator.pas

@@ -27,7 +27,7 @@ uses
   ClpBits,
   ClpCryptoLibTypes,
   ClpECKeyParameters,
-  ClpECAlgorithms,
+  ClpECCompUtilities,
   ClpIECKeyPairGenerator,
   ClpIAsn1Objects,
   ClpIKeyGenerationParameters,
@@ -35,7 +35,8 @@ uses
   ClpECDomainParameters,
   ClpIECDomainParameters,
   ClpIECC,
-  ClpIFixedPointCombMultiplier,
+  ClpMultipliers,
+  ClpIMultipliers,
   ClpSecObjectIdentifiers,
   ClpCustomNamedCurves,
   ClpECNamedCurveTable,
@@ -47,7 +48,6 @@ uses
   ClpIECPublicKeyParameters,
   ClpECPrivateKeyParameters,
   ClpIECPrivateKeyParameters,
-  ClpFixedPointCombMultiplier,
   ClpSecureRandom,
   ClpISecureRandom,
   ClpIAsymmetricCipherKeyPairGenerator;

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

@@ -31,7 +31,7 @@ uses
   ClpIParametersWithRandom,
   ClpIECPublicKeyParameters,
   ClpIECPrivateKeyParameters,
-  ClpFixedPointCombMultiplier,
+  ClpMultipliers,
   ClpCryptoLibTypes,
   ClpICipherParameters,
   ClpIECDomainParameters,

+ 102 - 45
CryptoLib/src/Crypto/Signers/ClpECNRSigner.pas

@@ -27,6 +27,7 @@ uses
   ClpIECC,
   ClpIECNRSigner,
   ClpBigInteger,
+  ClpBigIntegers,
   ClpISecureRandom,
   ClpIECKeyParameters,
   ClpIParametersWithRandom,
@@ -47,29 +48,45 @@ resourcestring
   SECPrivateKeyNotFound = 'EC Private Key Required for Signing';
   SNotInitializedForSigning = 'Not Initialised For Signing';
   SNotInitializedForVerifying = 'Not Initialised For Verifying';
+  SNotInitializedForVerifyingRecovery =
+    'Not Initialised For Verifying/Recovery';
   SInputTooLargeForECNRKey = 'Input Too Large For ECNR Key.';
 
 type
 
   /// <summary>
-  /// EC-NR as described in IEEE 1363-2000
+  /// EC-NR as described in IEEE 1363-2000 - a signature algorithm for Elliptic Curve which
+  /// also offers message recovery.
   /// </summary>
   TECNRSigner = class sealed(TInterfacedObject, IDsaExt, IECNRSigner)
 
   strict private
   var
-    FforSigning: Boolean;
-    Fkey: IECKeyParameters;
-    Frandom: ISecureRandom;
+    FForSigning: Boolean;
+    FKey: IECKeyParameters;
+    FRandom: ISecureRandom;
 
-    function GetAlgorithmName: String; virtual;
-    function GetOrder: TBigInteger; virtual;
+    function GetAlgorithmName: String;
+    function GetOrder: TBigInteger;
+
+    function ExtractT(const pubKey: IECPublicKeyParameters;
+      const r, s: TBigInteger): TBigInteger;
 
   public
 
     property Order: TBigInteger read GetOrder;
     property AlgorithmName: String read GetAlgorithmName;
 
+    /// <summary>
+    /// Initialise the signer.
+    /// </summary>
+    /// <param name="forSigning">
+    /// forSigning true if we are generating a signature, false for
+    /// verification or if we want to use the signer for message recovery.
+    /// </param>
+    /// <param name="parameters">
+    /// key parameters for signature generation.
+    /// </param>
     procedure Init(forSigning: Boolean;
       const parameters: ICipherParameters); virtual;
 
@@ -121,23 +138,72 @@ type
     function VerifySignature(const &message: TCryptoLibByteArray;
       const r, s: TBigInteger): Boolean;
 
+    /// <summary>
+    /// Returns the data used for the signature generation, assuming the
+    /// public key passed to Init() is correct.
+    /// </summary>
+    /// <returns>
+    /// null if r and s are not valid.
+    /// </returns>
+    function GetRecoveredMessage(const r, s: TBigInteger): TCryptoLibByteArray;
+
   end;
 
 implementation
 
 { TECNRSigner }
 
+function TECNRSigner.ExtractT(const pubKey: IECPublicKeyParameters;
+  const r, s: TBigInteger): TBigInteger;
+var
+  n, x: TBigInteger;
+  G, W, P: IECPoint;
+begin
+  n := pubKey.parameters.n;
+
+  // r in the range [1,n-1]
+  if ((r.CompareTo(TBigInteger.ONE) < 0) or (r.CompareTo(n) >= 0)) then
+  begin
+    result := Default (TBigInteger);
+    Exit;
+  end;
+
+  // s in the range [0,n-1]           NB: ECNR spec says 0
+  if ((s.CompareTo(TBigInteger.ZERO) < 0) or (s.CompareTo(n) >= 0)) then
+  begin
+    result := Default (TBigInteger);
+    Exit;
+  end;
+
+  // compute P = sG + rW
+
+  G := pubKey.parameters.G;
+  W := pubKey.Q;
+  // calculate P using Bouncy math
+  P := TECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize();
+
+  // components must be bogus.
+  if (P.IsInfinity) then
+  begin
+    result := Default (TBigInteger);
+    Exit;
+  end;
+
+  x := P.AffineXCoord.ToBigInteger();
+
+  result := r.Subtract(x).&Mod(n);
+end;
+
 function TECNRSigner.GenerateSignature(const &message: TCryptoLibByteArray)
   : TCryptoLibGenericArray<TBigInteger>;
 var
   n, e, r, s, Vx, x, u: TBigInteger;
-  nBitLength, eBitLength: Int32;
   privKey: IECPrivateKeyParameters;
   tempPair: IAsymmetricCipherKeyPair;
   keyGen: IECKeyPairGenerator;
   V: IECPublicKeyParameters;
 begin
-  if (not FforSigning) then
+  if (not FForSigning) then
   begin
     // not properly initialized... deal with it
     raise EInvalidOperationCryptoLibException.CreateRes
@@ -145,14 +211,12 @@ begin
   end;
 
   n := Order;
-  nBitLength := n.BitLength;
 
   e := TBigInteger.Create(1, &message);
-  eBitLength := e.BitLength;
 
-  privKey := Fkey as IECPrivateKeyParameters;
+  privKey := FKey as IECPrivateKeyParameters;
 
-  if (eBitLength > nBitLength) then
+  if (e.CompareTo(n) >= 0) then
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputTooLargeForECNRKey);
   end;
@@ -162,7 +226,7 @@ begin
     // the same EC parameters
     keyGen := TECKeyPairGenerator.Create();
 
-    keyGen.Init(TECKeyGenerationParameters.Create(privKey.parameters, Frandom)
+    keyGen.Init(TECKeyGenerationParameters.Create(privKey.parameters, FRandom)
       as IECKeyGenerationParameters);
 
     tempPair := keyGen.GenerateKeyPair();
@@ -189,7 +253,7 @@ end;
 
 function TECNRSigner.GetOrder: TBigInteger;
 begin
-  result := Fkey.parameters.n;
+  result := FKey.parameters.n;
 end;
 
 procedure TECNRSigner.Init(forSigning: Boolean;
@@ -198,19 +262,19 @@ var
   rParam: IParametersWithRandom;
   Lparameters: ICipherParameters;
 begin
-  FforSigning := forSigning;
+  FForSigning := forSigning;
   Lparameters := parameters;
   if (forSigning) then
   begin
 
     if (Supports(Lparameters, IParametersWithRandom, rParam)) then
     begin
-      Frandom := rParam.random;
+      FRandom := rParam.random;
       Lparameters := rParam.parameters;
     end
     else
     begin
-      Frandom := TSecureRandom.Create();
+      FRandom := TSecureRandom.Create();
     end;
 
     if (not(Supports(Lparameters, IECPrivateKeyParameters))) then
@@ -218,7 +282,7 @@ begin
       raise EInvalidKeyCryptoLibException.CreateRes(@SECPrivateKeyNotFound);
     end;
 
-    Fkey := Lparameters as IECPrivateKeyParameters;
+    FKey := Lparameters as IECPrivateKeyParameters;
   end
   else
   begin
@@ -227,7 +291,7 @@ begin
       raise EInvalidKeyCryptoLibException.CreateRes(@SECPublicKeyNotFound);
     end;
 
-    Fkey := Lparameters as IECPublicKeyParameters;
+    FKey := Lparameters as IECPublicKeyParameters;
   end;
 end;
 
@@ -235,18 +299,17 @@ function TECNRSigner.VerifySignature(const &message: TCryptoLibByteArray;
   const r, s: TBigInteger): Boolean;
 var
   pubKey: IECPublicKeyParameters;
-  n, e, x, t: TBigInteger;
+  n, e, t: TBigInteger;
   nBitLength, eBitLength: Int32;
-  G, W, P: IECPoint;
 begin
-  if (FforSigning) then
+  if (FForSigning) then
   begin
     // not properly initialized... deal with it
     raise EInvalidOperationCryptoLibException.CreateRes
       (@SNotInitializedForVerifying);
   end;
 
-  pubKey := Fkey as IECPublicKeyParameters;
+  pubKey := FKey as IECPublicKeyParameters;
   n := pubKey.parameters.n;
   nBitLength := n.BitLength;
 
@@ -258,37 +321,31 @@ begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputTooLargeForECNRKey);
   end;
 
-  // r in the range [1,n-1]
-  if ((r.CompareTo(TBigInteger.One) < 0) or (r.CompareTo(n) >= 0)) then
-  begin
-    result := false;
-    Exit;
-  end;
+  t := ExtractT(pubKey, r, s);
 
-  // s in the range [0,n-1]           NB: ECNR spec says 0
-  if ((s.CompareTo(TBigInteger.Zero) < 0) or (s.CompareTo(n) >= 0)) then
+  result := (t.IsInitialized) and (t.Equals(e.&Mod(n)));
+end;
+
+function TECNRSigner.GetRecoveredMessage(const r, s: TBigInteger)
+  : TCryptoLibByteArray;
+var
+  t: TBigInteger;
+begin
+  if (FForSigning) then
   begin
-    result := false;
-    Exit;
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifyingRecovery);
   end;
 
-  // compute P = sG + rW
+  t := ExtractT(FKey as IECPublicKeyParameters, r, s);
 
-  G := pubKey.parameters.G;
-  W := pubKey.Q;
-  // calculate P using ECAlgorithms Math
-  P := TECAlgorithms.SumOfTwoMultiplies(G, s, W, r).Normalize();
-
-  if (P.IsInfinity) then
+  if (t.IsInitialized) then
   begin
-    result := false;
+    result := TBigIntegers.AsUnsignedByteArray(t);
     Exit;
   end;
 
-  x := P.AffineXCoord.ToBigInteger();
-  t := r.Subtract(x).&Mod(n);
-
-  result := t.Equals(e);
+  result := Nil;
 end;
 
 end.

+ 6 - 0
CryptoLib/src/Include/CryptoLib.inc

@@ -136,6 +136,12 @@
    {$DEFINE SHIFT_OVERFLOW_BUG_FIXED}
 {$IFEND}
 
+  // 10.1 Berlin and Above
+{$IF CompilerVersion >= 31.0}
+   {$DEFINE DELPHI10.1_BERLIN_UP}
+   {$DEFINE HAS_VOLATILE}
+{$IFEND}
+
   // 10.2 Tokyo and Above
 {$IF CompilerVersion >= 32.0}
    {$DEFINE DELPHI10.2_TOKYO_UP}

+ 4 - 0
CryptoLib/src/Include/CryptoLibHelper.inc

@@ -24,3 +24,7 @@
 {$IF FPC_FULLVERSION < 30004}
    {$MESSAGE ERROR 'This Library requires FreePascal 3.0.4 or higher.'}
 {$IFEND}
+
+{$IF FPC_FULLVERSION >= 30301}
+   {$DEFINE HAS_VOLATILE}
+{$IFEND}

+ 1 - 1
CryptoLib/src/Interfaces/ClpICurve25519Custom.pas

@@ -55,7 +55,7 @@ type
   end;
 
 type
-  ICurve25519LookupTable = Interface(IECLookupTable)
+  ICurve25519LookupTable = Interface(IAbstractECLookupTable)
     ['{79FE1276-3D22-4A20-A4F1-58F0C0532BAC}']
   end;
 

+ 19 - 2
CryptoLib/src/Interfaces/ClpIECC.pas

@@ -118,6 +118,7 @@ type
 
     function Trace(): Int32;
     function HalfTrace(): IECFieldElement;
+    function HasFastTrace(): Boolean;
   end;
 
 type
@@ -252,6 +253,9 @@ type
     function ScaleX(const scale: IECFieldElement): IECPoint;
     function ScaleY(const scale: IECFieldElement): IECPoint;
 
+    function ScaleXNegateY(const scale: IECFieldElement): IECPoint;
+    function ScaleYNegateX(const scale: IECFieldElement): IECPoint;
+
     function GetEncoded(): TCryptoLibByteArray; overload;
     function GetEncoded(compressed: Boolean): TCryptoLibByteArray; overload;
 
@@ -591,11 +595,24 @@ type
     ['{A1839961-4FBF-42EF-BF8B-6084064A05C1}']
     function GetSize: Int32;
     function Lookup(index: Int32): IECPoint;
+    function LookupVar(index: Int32): IECPoint;
     property Size: Int32 read GetSize;
   end;
 
 type
-  IDefaultLookupTable = interface(IECLookupTable)
+  IAbstractECLookupTable = interface(IECLookupTable)
+    ['{9695E807-6A2A-4879-8438-84CE029AD143}']
+
+  end;
+
+type
+  ISimpleLookupTable = interface(IAbstractECLookupTable)
+    ['{5C2C8292-CECE-4A01-89D2-AF75B55F6FA3}']
+
+  end;
+
+type
+  IDefaultLookupTable = interface(IAbstractECLookupTable)
     ['{094881EB-24A6-41A3-BAD6-D6DAB13DD17D}']
 
   end;
@@ -607,7 +624,7 @@ type
   end;
 
 type
-  IDefaultF2mLookupTable = interface(IECLookupTable)
+  IDefaultF2mLookupTable = interface(IAbstractECLookupTable)
     ['{0C019049-9839-4322-BAF5-8E5D39BC426D}']
 
   end;

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

@@ -30,6 +30,8 @@ type
   IECNRSigner = interface(IDsaExt)
     ['{C136F005-404E-4022-886E-DE5EFCECFF9C}']
 
+    function GetRecoveredMessage(const r, s: TBigInteger): TCryptoLibByteArray;
+
   end;
 
 implementation

+ 47 - 0
CryptoLib/src/Interfaces/ClpIEndoPreCompInfo.pas

@@ -0,0 +1,47 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEndoPreCompInfo;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIECC,
+  ClpIPreCompInfo;
+
+type
+  IEndoPreCompInfo = interface(IPreCompInfo)
+    ['{84C79A80-8162-4079-8146-AA1D46A739ED}']
+
+    function GetEndomorphism: IECEndomorphism;
+    procedure SetEndomorphism(const value: IECEndomorphism);
+
+    property Endomorphism: IECEndomorphism read GetEndomorphism
+      write SetEndomorphism;
+
+    function GetMappedPoint: IECPoint;
+    procedure SetMappedPoint(const value: IECPoint);
+
+    property MappedPoint: IECPoint read GetMappedPoint write SetMappedPoint;
+
+  end;
+
+implementation
+
+end.

+ 4 - 4
CryptoLib/src/Interfaces/ClpIGlvMultiplier.pas → CryptoLib/src/Interfaces/ClpIGlvTypeAEndomorphism.pas

@@ -15,7 +15,7 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIGlvMultiplier;
+unit ClpIGlvTypeAEndomorphism;
 
 {$I ..\Include\CryptoLib.inc}
 
@@ -23,11 +23,11 @@ interface
 
 uses
   ClpBigInteger,
-  ClpIAbstractECMultiplier;
+  ClpIGlvEndomorphism;
 
 type
-  IGlvMultiplier = interface(IAbstractECMultiplier)
-    ['{F54D54F5-F544-421B-89FC-1D8058FB8F33}']
+  IGlvTypeAEndomorphism = interface(IGlvEndomorphism)
+    ['{961A1588-7D37-46C5-BC67-F71063641B42}']
 
   end;
 

+ 14 - 17
CryptoLib/src/Interfaces/ClpIWNafL2RMultiplier.pas → CryptoLib/src/Interfaces/ClpIGlvTypeAParameters.pas

@@ -15,7 +15,7 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIWNafL2RMultiplier;
+unit ClpIGlvTypeAParameters;
 
 {$I ..\Include\CryptoLib.inc}
 
@@ -23,24 +23,21 @@ interface
 
 uses
   ClpBigInteger,
-  ClpIAbstractECMultiplier;
+  ClpIScalarSplitParameters,
+  ClpCryptoLibTypes;
 
 type
-  IWNafL2RMultiplier = interface(IAbstractECMultiplier)
-
-    ['{E2A5E4EF-C092-4F83-ACCF-0FC8731FB274}']
-
-    /// <summary>
-    /// Determine window width to use for a scalar multiplication of the
-    /// given size.
-    /// </summary>
-    /// <param name="bits">
-    /// the bit-length of the scalar to multiply by
-    /// </param>
-    /// <returns>
-    /// the window size to use
-    /// </returns>
-    function GetWindowSize(bits: Int32): Int32;
+
+  IGlvTypeAParameters = interface(IInterface)
+    ['{B5DDABB5-B51C-41F4-B2FD-6C8733300502}']
+
+    function GetI: TBigInteger;
+    function GetLambda: TBigInteger;
+    function GetSplitParams: IScalarSplitParameters;
+
+    property I: TBigInteger read GetI;
+    property lambda: TBigInteger read GetLambda;
+    property splitParams: IScalarSplitParameters read GetSplitParams;
 
   end;
 

+ 0 - 2
CryptoLib/src/Interfaces/ClpIGlvTypeBEndomorphism.pas

@@ -29,8 +29,6 @@ type
   IGlvTypeBEndomorphism = interface(IGlvEndomorphism)
     ['{4F285F6A-F627-4873-9F4C-FBC7A7B83A9C}']
 
-    function CalculateB(const k, g: TBigInteger; t: Int32): TBigInteger;
-
   end;
 
 implementation

+ 4 - 15
CryptoLib/src/Interfaces/ClpIGlvTypeBParameters.pas

@@ -23,6 +23,7 @@ interface
 
 uses
   ClpBigInteger,
+  ClpIScalarSplitParameters,
   ClpCryptoLibTypes;
 
 type
@@ -30,25 +31,13 @@ type
   IGlvTypeBParameters = interface(IInterface)
     ['{089AC2AB-15A1-47F5-BED0-C09EA77BECB9}']
 
-    function GetG1: TBigInteger;
-    function GetG2: TBigInteger;
-    function GetV1A: TBigInteger;
-    function GetV1B: TBigInteger;
-    function GetV2A: TBigInteger;
-    function GetV2B: TBigInteger;
     function GetLambda: TBigInteger;
     function GetBeta: TBigInteger;
-    function GetBits: Int32;
-
-    property g1: TBigInteger read GetG1;
-    property g2: TBigInteger read GetG2;
-    property V1A: TBigInteger read GetV1A;
-    property V1B: TBigInteger read GetV1B;
-    property V2A: TBigInteger read GetV2A;
-    property V2B: TBigInteger read GetV2B;
+    function GetSplitParams: IScalarSplitParameters;
+
     property lambda: TBigInteger read GetLambda;
     property beta: TBigInteger read GetBeta;
-    property bits: Int32 read GetBits;
+    property splitParams: IScalarSplitParameters read GetSplitParams;
 
   end;
 

+ 30 - 3
CryptoLib/src/Interfaces/ClpIWTauNafMultiplier.pas → CryptoLib/src/Interfaces/ClpIMultipliers.pas

@@ -15,7 +15,7 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIWTauNafMultiplier;
+unit ClpIMultipliers;
 
 {$I ..\Include\CryptoLib.inc}
 
@@ -23,9 +23,36 @@ interface
 
 uses
   ClpBigInteger,
-  ClpIECC,
   ClpIZTauElement,
-  ClpIAbstractECMultiplier;
+  ClpIECC;
+
+type
+  IAbstractECMultiplier = interface(IECMultiplier)
+    ['{DD63984C-7D4D-46DE-9004-20FD909C2EFB}']
+
+    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
+      : IECPoint;
+
+  end;
+
+type
+  IFixedPointCombMultiplier = interface(IAbstractECMultiplier)
+    ['{A3345E31-4D5C-4442-9C3D-ACC7F6DA4A14}']
+
+  end;
+
+type
+  IGlvMultiplier = interface(IAbstractECMultiplier)
+    ['{F54D54F5-F544-421B-89FC-1D8058FB8F33}']
+
+  end;
+
+type
+  IWNafL2RMultiplier = interface(IAbstractECMultiplier)
+
+    ['{E2A5E4EF-C092-4F83-ACCF-0FC8731FB274}']
+
+  end;
 
 type
   IWTauNafMultiplier = interface(IAbstractECMultiplier)

+ 52 - 0
CryptoLib/src/Interfaces/ClpIScalarSplitParameters.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 ClpIScalarSplitParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIGlvEndomorphism;
+
+type
+  IScalarSplitParameters = interface(IInterface)
+    ['{C36FF223-C4F3-4483-B280-A50EF95497AF}']
+
+    function GetG1: TBigInteger;
+    function GetG2: TBigInteger;
+    function GetV1A: TBigInteger;
+    function GetV1B: TBigInteger;
+    function GetV2A: TBigInteger;
+    function GetV2B: TBigInteger;
+    function GetBits: Int32;
+
+    property g1: TBigInteger read GetG1;
+    property g2: TBigInteger read GetG2;
+    property V1A: TBigInteger read GetV1A;
+    property V1B: TBigInteger read GetV1B;
+    property V2A: TBigInteger read GetV2A;
+    property V2B: TBigInteger read GetV2B;
+    property bits: Int32 read GetBits;
+
+  end;
+
+implementation
+
+end.

+ 5 - 4
CryptoLib/src/Interfaces/ClpIFixedPointCombMultiplier.pas → CryptoLib/src/Interfaces/ClpIScaleXNegateYPointMap.pas

@@ -15,18 +15,19 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIFixedPointCombMultiplier;
+unit ClpIScaleXNegateYPointMap;
 
 {$I ..\Include\CryptoLib.inc}
 
 interface
 
 uses
-  ClpIAbstractECMultiplier;
+  ClpIECC;
 
 type
-  IFixedPointCombMultiplier = interface(IAbstractECMultiplier)
-    ['{A3345E31-4D5C-4442-9C3D-ACC7F6DA4A14}']
+  IScaleXNegateYPointMap = interface(IECPointMap)
+
+    ['{D4FF6900-B627-45AB-8066-00E763213CE5}']
 
   end;
 

+ 3 - 7
CryptoLib/src/Interfaces/ClpIAbstractECMultiplier.pas → CryptoLib/src/Interfaces/ClpIScaleYNegateXPointMap.pas

@@ -15,23 +15,19 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIAbstractECMultiplier;
+unit ClpIScaleYNegateXPointMap;
 
 {$I ..\Include\CryptoLib.inc}
 
 interface
 
 uses
-  ClpBigInteger,
   ClpIECC;
 
 type
+  IScaleYNegateXPointMap = interface(IECPointMap)
 
-  IAbstractECMultiplier = interface(IECMultiplier)
-    ['{DD63984C-7D4D-46DE-9004-20FD909C2EFB}']
-
-    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
-      : IECPoint;
+    ['{6284EFA2-DE75-437F-86D3-DD93BCAF511B}']
 
   end;
 

+ 1 - 1
CryptoLib/src/Interfaces/ClpISecP256K1Custom.pas

@@ -50,7 +50,7 @@ type
   end;
 
 type
-  ISecP256K1LookupTable = Interface(IECLookupTable)
+  ISecP256K1LookupTable = Interface(IAbstractECLookupTable)
     ['{0E204483-F303-49FD-AF66-0F30CF855CA9}']
   end;
 

+ 1 - 1
CryptoLib/src/Interfaces/ClpISecP256R1Custom.pas

@@ -50,7 +50,7 @@ type
   end;
 
 type
-  ISecP256R1LookupTable = Interface(IECLookupTable)
+  ISecP256R1LookupTable = Interface(IAbstractECLookupTable)
     ['{87BF97BA-18D2-4248-ABEB-8E429998E9D9}']
   end;
 

+ 1 - 1
CryptoLib/src/Interfaces/ClpISecP384R1Custom.pas

@@ -50,7 +50,7 @@ type
   end;
 
 type
-  ISecP384R1LookupTable = Interface(IECLookupTable)
+  ISecP384R1LookupTable = Interface(IAbstractECLookupTable)
     ['{F1354F0B-577F-402C-A363-7761CF82DA43}']
   end;
 

+ 1 - 1
CryptoLib/src/Interfaces/ClpISecP521R1Custom.pas

@@ -50,7 +50,7 @@ type
   end;
 
 type
-  ISecP521R1LookupTable = Interface(IECLookupTable)
+  ISecP521R1LookupTable = Interface(IAbstractECLookupTable)
     ['{3A647191-94A9-483D-9AC5-57FEFDBA3060}']
   end;
 

+ 1 - 1
CryptoLib/src/Interfaces/ClpISecT283Custom.pas

@@ -74,7 +74,7 @@ type
   end;
 
 type
-  ISecT283K1LookupTable = Interface(IECLookupTable)
+  ISecT283K1LookupTable = Interface(IAbstractECLookupTable)
     ['{3AF41553-A108-46D6-9CCC-AB1814A0A247}']
   end;
 

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

@@ -15,7 +15,7 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIValidityPrecompInfo;
+unit ClpIValidityPreCompInfo;
 
 {$I ..\Include\CryptoLib.inc}
 
@@ -25,7 +25,7 @@ uses
   ClpIPreCompInfo;
 
 type
-  IValidityPrecompInfo = interface(IPreCompInfo)
+  IValidityPreCompInfo = interface(IPreCompInfo)
 
     ['{2339F5CA-A4B3-4E95-B358-4D4F4CA97EB3}']
 

+ 18 - 0
CryptoLib/src/Interfaces/ClpIWNafPreCompInfo.pas

@@ -37,12 +37,30 @@ type
     function GetTwice: IECPoint;
     procedure SetTwice(const Value: IECPoint);
 
+    function GetConfWidth: Int32;
+    procedure SetConfWidth(Value: Int32);
+
+    function GetWidth: Int32;
+    procedure SetWidth(Value: Int32);
+
+    function GetPromotionCountdown: Int32;
+    procedure SetPromotionCountdown(Value: Int32);
+
+    function DecrementPromotionCountdown: Int32;
+
+    function IsPromoted: Boolean;
+
     property PreComp: TCryptoLibGenericArray<IECPoint> read GetPreComp
       write SetPreComp;
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
       write SetPreCompNeg;
     property Twice: IECPoint read GetTwice write SetTwice;
 
+    property ConfWidth: Int32 read GetConfWidth write SetConfWidth;
+    property Width: Int32 read GetWidth write SetWidth;
+    property PromotionCountdown: Int32 read GetPromotionCountdown
+      write SetPromotionCountdown;
+
   end;
 
 implementation

+ 242 - 973
CryptoLib/src/Math/EC/ClpECAlgorithms.pas

@@ -25,17 +25,18 @@ uses
   SysUtils,
   Math,
   ClpCryptoLibTypes,
-  ClpBits,
   ClpBigInteger,
-  ClpWNafPreCompInfo,
-  ClpIPolynomialExtensionField,
-  ClpIGlvEndomorphism,
-  ClpIWNafPreCompInfo,
-  ClpIPreCompInfo,
-  ClpIPreCompCallBack,
+  ClpBits,
+  ClpNat,
   ClpIECC,
-  ClpECCurveConstants,
-  ClpIFiniteField;
+  ClpECCompUtilities,
+  ClpIWNafPreCompInfo,
+  ClpIFiniteField,
+  ClpIFixedPointPreCompInfo,
+  ClpIGlvEndomorphism,
+  ClpIMultipliers,
+  ClpMultipliers,
+  ClpIPolynomialExtensionField;
 
 resourcestring
   SInvalidArray =
@@ -43,160 +44,8 @@ resourcestring
   SInvalidPointLocation = 'Point Must be on the Same Curve';
   SInvalidPoint = 'Invalid Point, "P"';
   SInvalidResult = 'Invalid Result';
-  SInvalidRange = 'Must be in the Range [2, 16], "width"';
-  SInvalidRange2 = 'Must be in the Range [2, 8], "width"';
-
-type
-  TWNafUtilities = class abstract(TObject)
-
-  strict private
-  const
-    FDEFAULT_WINDOW_SIZE_CUTOFFS: array [0 .. 5] of Int32 = (13, 41, 121, 337,
-      897, 2305);
-
-  class var
-    FEMPTY_BYTES: TCryptoLibByteArray;
-    FEMPTY_INTS: TCryptoLibInt32Array;
-
-  type
-    IMapPointCallback = interface(IPreCompCallback)
-      ['{730BF27F-D5C3-4DF4-AC77-B8653C457C10}']
-
-    end;
-
-  type
-    TMapPointCallback = class(TInterfacedObject, IPreCompCallback,
-      IMapPointCallback)
-
-    strict private
-    var
-      Fm_wnafPreCompP: IWNafPreCompInfo;
-      Fm_includeNegated: Boolean;
-      Fm_pointMap: IECPointMap;
-
-    public
-      constructor Create(const wnafPreCompP: IWNafPreCompInfo;
-        includeNegated: Boolean; const pointMap: IECPointMap);
-
-      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
-
-    end;
-
-  type
-    IWNafCallback = interface(IPreCompCallback)
-      ['{A439A606-7899-4720-937E-C2F3D94D4811}']
-
-    end;
-
-  type
-    TWNafCallback = class(TInterfacedObject, IPreCompCallback, IWNafCallback)
-
-    strict private
-
-    var
-      Fm_p: IECPoint;
-      Fm_width: Int32;
-      Fm_includeNegated: Boolean;
-
-    public
-      constructor Create(const p: IECPoint; width: Int32;
-        includeNegated: Boolean);
-
-      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
-
-    end;
-
-  class function CheckExisting(const existingWNaf: IWNafPreCompInfo;
-    reqPreCompLen: Int32; includeNegated: Boolean): Boolean; static; inline;
-
-  class function CheckTable(const table: TCryptoLibGenericArray<IECPoint>;
-    reqLen: Int32): Boolean; static; inline;
-
-  class function Trim(const a: TCryptoLibByteArray; length: Int32)
-    : TCryptoLibByteArray; overload; static; inline;
-
-  class function Trim(const a: TCryptoLibInt32Array; length: Int32)
-    : TCryptoLibInt32Array; overload; static; inline;
-
-  class function ResizeTable(const a: TCryptoLibGenericArray<IECPoint>;
-    length: Int32): TCryptoLibGenericArray<IECPoint>; static; inline;
-
-  class procedure Boot(); static;
-  class constructor CreateWNafUtilities();
-
-  public
-
-    const
-    PRECOMP_NAME: String = 'bc_wnaf';
-
-    class function GenerateCompactNaf(const k: TBigInteger)
-      : TCryptoLibInt32Array; static;
-    class function GenerateCompactWindowNaf(width: Int32; const k: TBigInteger)
-      : TCryptoLibInt32Array; static;
-
-    class function GenerateJsf(const g, h: TBigInteger)
-      : TCryptoLibByteArray; static;
-    class function GenerateNaf(const k: TBigInteger)
-      : TCryptoLibByteArray; static;
-    // /**
-    // * Computes the Window NAF (non-adjacent Form) of an integer.
-    // * @param width The width <code>w</code> of the Window NAF. The width is
-    // * defined as the minimal number <code>w</code>, such that for any
-    // * <code>w</code> consecutive digits in the resulting representation, at
-    // * most one is non-zero.
-    // * @param k The integer of which the Window NAF is computed.
-    // * @return The Window NAF of the given width, such that the following holds:
-    // * <code>k = &amp;sum;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
-    // * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
-    // * returned <code>byte[]</code>.
-    // */
-    class function GenerateWindowNaf(width: Int32; const k: TBigInteger)
-      : TCryptoLibByteArray; static;
-
-    class function GetNafWeight(const k: TBigInteger): Int32; static; inline;
-
-    class function GetWNafPreCompInfo(const p: IECPoint): IWNafPreCompInfo;
-      overload; static; inline;
-
-    class function GetWNafPreCompInfo(const preCompInfo: IPreCompInfo)
-      : IWNafPreCompInfo; overload; static; inline;
-
-    /// <summary>
-    /// Determine window width to use for a scalar multiplication of the
-    /// given size.
-    /// </summary>
-    /// <param name="bits">
-    /// the bit-length of the scalar to multiply by
-    /// </param>
-    /// <returns>
-    /// the window size to use
-    /// </returns>
-    class function GetWindowSize(bits: Int32): Int32; overload; static; inline;
-
-    /// <summary>
-    /// Determine window width to use for a scalar multiplication of the
-    /// given size.
-    /// </summary>
-    /// <param name="bits">
-    /// the bit-length of the scalar to multiply by
-    /// </param>
-    /// <param name="windowSizeCutoffs">
-    /// a monotonically increasing list of bit sizes at which to increment
-    /// the window width
-    /// </param>
-    /// <returns>
-    /// the window size to use
-    /// </returns>
-    class function GetWindowSize(bits: Int32;
-      const windowSizeCutoffs: array of Int32): Int32; overload; static;
-
-    class function MapPointWithPrecomp(const p: IECPoint; width: Int32;
-      includeNegated: Boolean; const pointMap: IECPointMap): IECPoint; static;
-
-    class function Precompute(const p: IECPoint; width: Int32;
-      includeNegated: Boolean): IWNafPreCompInfo; static;
-
-  end;
+  SInvalidComputation =
+    'Fixed-Point Comb Doesn''t Support Scalars Larger Than The Curve Order';
 
 type
   TECAlgorithms = class sealed(TObject)
@@ -212,6 +61,10 @@ type
       const infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
       const wnafs: TCryptoLibMatrixByteArray): IECPoint; overload; static;
 
+    class function ImplShamirsTrickFixedPoint(const p: IECPoint;
+      const k: TBigInteger; const q: IECPoint; const l: TBigInteger)
+      : IECPoint; static;
+
   public
     class function IsF2mCurve(const c: IECCurve): Boolean; static;
     class function IsF2mField(const field: IFiniteField): Boolean; static;
@@ -222,7 +75,7 @@ type
       const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint; static;
 
     class function SumOfTwoMultiplies(const p: IECPoint; const a: TBigInteger;
-      const Q: IECPoint; const b: TBigInteger): IECPoint; static;
+      const q: IECPoint; const b: TBigInteger): IECPoint; static;
 
     // /*
     // * "Shamir's Trick", originally due to E. G. Straus
@@ -243,7 +96,7 @@ type
     // * 9: return R
     // */
     class function ShamirsTrick(const p: IECPoint; const k: TBigInteger;
-      const Q: IECPoint; const l: TBigInteger): IECPoint; static;
+      const q: IECPoint; const l: TBigInteger): IECPoint; static;
 
     class function ImportPoint(const c: IECCurve; const p: IECPoint)
       : IECPoint; static;
@@ -277,14 +130,13 @@ type
       : IECPoint; static;
 
     class function ImplShamirsTrickJsf(const p: IECPoint; const k: TBigInteger;
-      const Q: IECPoint; const l: TBigInteger): IECPoint; static;
+      const q: IECPoint; const l: TBigInteger): IECPoint; static;
 
     class function ImplShamirsTrickWNaf(const p: IECPoint; const k: TBigInteger;
-      const Q: IECPoint; const l: TBigInteger): IECPoint; overload; static;
+      const q: IECPoint; const l: TBigInteger): IECPoint; overload; static;
 
-    class function ImplShamirsTrickWNaf(const p: IECPoint; const k: TBigInteger;
-      const pointMapQ: IECPointMap; const l: TBigInteger): IECPoint;
-      overload; static;
+    class function ImplShamirsTrickWNaf(const endomorphism: IECEndomorphism;
+      const p: IECPoint; const k, l: TBigInteger): IECPoint; overload; static;
 
     class function ImplSumOfMultiplies
       (const ps: TCryptoLibGenericArray<IECPoint>;
@@ -296,8 +148,8 @@ type
       const ks: TCryptoLibGenericArray<TBigInteger>;
       const glvEndomorphism: IGlvEndomorphism): IECPoint; static;
 
-    class function ImplSumOfMultiplies
-      (const ps: TCryptoLibGenericArray<IECPoint>; const pointMap: IECPointMap;
+    class function ImplSumOfMultiplies(const endomorphism: IECEndomorphism;
+      const ps: TCryptoLibGenericArray<IECPoint>;
       const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint;
       overload; static;
 
@@ -341,33 +193,124 @@ begin
   result := p;
 end;
 
+class function TECAlgorithms.ImplShamirsTrickFixedPoint(const p: IECPoint;
+  const k: TBigInteger; const q: IECPoint; const l: TBigInteger): IECPoint;
+var
+  c: IECCurve;
+  combSize, widthP, widthQ, width, d, fullComb, i, top, j: Int32;
+  infoP, infoQ: IFixedPointPreCompInfo;
+  lookupTableP, lookupTableQ: IECLookupTable;
+  m: IFixedPointCombMultiplier;
+  r1, r2, R, addP, addQ, t: IECPoint;
+  BigK, BigL: TCryptoLibUInt32Array;
+  secretBitK, secretBitL, secretIndexK, secretIndexL: UInt32;
+begin
+  c := p.Curve;
+  combSize := TFixedPointUtilities.GetCombSize(c);
+
+  if (((k.BitLength) > combSize) or (l.BitLength > combSize)) then
+  begin
+    (*
+      * TODO The comb works best when the scalars are less than the (possibly unknown) order.
+      * Still, if we want to handle larger scalars, we could allow customization of the comb
+      * size, or alternatively we could deal with the 'extra' bits either by running the comb
+      * multiple times as necessary, or by using an alternative multiplier as prelude.
+    *)
+    raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidComputation);
+  end;
+
+  infoP := TFixedPointUtilities.Precompute(p);
+  infoQ := TFixedPointUtilities.Precompute(q);
+
+  lookupTableP := infoP.LookupTable;
+  lookupTableQ := infoQ.LookupTable;
+
+  widthP := infoP.width;
+  widthQ := infoQ.width;
+
+  // TODO This shouldn't normally happen, but a better "solution" is desirable anyway
+  if (widthP <> widthQ) then
+  begin
+    m := TFixedPointCombMultiplier.Create();
+    r1 := m.Multiply(p, k);
+    r2 := m.Multiply(q, l);
+    result := r1.Add(r2);
+    Exit;
+  end;
+
+  width := widthP;
+
+  d := ((combSize + width) - 1) div width;
+
+  R := c.Infinity;
+
+  fullComb := d * width;
+  BigK := TNat.FromBigInteger(fullComb, k);
+  BigL := TNat.FromBigInteger(fullComb, l);
+
+  top := fullComb - 1;
+
+  for i := 0 to System.Pred(d) do
+  begin
+    secretIndexK := 0;
+    secretIndexL := 0;
+
+    j := top - i;
+
+    while j >= 0 do
+    begin
+
+      secretBitK := BigK[TBits.Asr32(j, 5)] shr (j and $1F);
+      secretIndexK := secretIndexK xor (secretBitK shr 1);
+      secretIndexK := secretIndexK shl 1;
+      secretIndexK := secretIndexK xor secretBitK;
+
+      secretBitL := BigL[TBits.Asr32(j, 5)] shr (j and $1F);
+      secretIndexL := secretIndexL xor (secretBitL shr 1);
+      secretIndexL := secretIndexL shl 1;
+      secretIndexL := secretIndexL xor secretBitL;
+
+      System.Dec(j, d);
+    end;
+
+    addP := lookupTableP.LookupVar(Int32(secretIndexK));
+    addQ := lookupTableQ.LookupVar(Int32(secretIndexL));
+
+    t := addP.Add(addQ);
+
+    R := R.TwicePlus(t);
+  end;
+
+  result := R.Add(infoP.Offset).Add(infoQ.Offset);
+end;
+
 class function TECAlgorithms.ImplShamirsTrickJsf(const p: IECPoint;
-  const k: TBigInteger; const Q: IECPoint; const l: TBigInteger): IECPoint;
+  const k: TBigInteger; const q: IECPoint; const l: TBigInteger): IECPoint;
 var
   Curve: IECCurve;
-  infinity, R: IECPoint;
+  Infinity, R: IECPoint;
   PaddQ, PsubQ: IECPoint;
   points, table: TCryptoLibGenericArray<IECPoint>;
   jsf: TCryptoLibByteArray;
   i, jsfi, kDigit, lDigit, index: Int32;
 begin
   Curve := p.Curve;
-  infinity := Curve.infinity;
+  Infinity := Curve.Infinity;
 
   // TODO conjugate co-Z addition (ZADDC) can return both of these
-  PaddQ := p.Add(Q);
-  PsubQ := p.Subtract(Q);
+  PaddQ := p.Add(q);
+  PsubQ := p.Subtract(q);
 
-  points := TCryptoLibGenericArray<IECPoint>.Create(Q, PsubQ, p, PaddQ);
+  points := TCryptoLibGenericArray<IECPoint>.Create(q, PsubQ, p, PaddQ);
   Curve.NormalizeAll(points);
 
   table := TCryptoLibGenericArray<IECPoint>.Create(points[3].Negate(),
-    points[2].Negate(), points[1].Negate(), points[0].Negate(), infinity,
+    points[2].Negate(), points[1].Negate(), points[0].Negate(), Infinity,
     points[0], points[1], points[2], points[3]);
 
   jsf := TWNafUtilities.GenerateJsf(k, l);
 
-  R := infinity;
+  R := Infinity;
 
   i := System.length(jsf);
   System.Dec(i);
@@ -387,13 +330,12 @@ begin
   result := R;
 end;
 
-class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint;
-  const k: TBigInteger; const pointMapQ: IECPointMap; const l: TBigInteger)
-  : IECPoint;
+class function TECAlgorithms.ImplShamirsTrickWNaf(const endomorphism
+  : IECEndomorphism; const p: IECPoint; const k, l: TBigInteger): IECPoint;
 var
   negK, negL: Boolean;
-  width: Int32;
-  Q: IECPoint;
+  minWidth, widthP, widthQ: Int32;
+  q: IECPoint;
   infoP, infoQ: IWNafPreCompInfo;
   preCompP, preCompQ, preCompNegP, preCompNegQ
     : TCryptoLibGenericArray<IECPoint>;
@@ -408,12 +350,15 @@ begin
   LK := LK.Abs();
   LL := LL.Abs();
 
-  width := Max(2, Min(16, TWNafUtilities.GetWindowSize(Max(LK.BitLength,
-    LL.BitLength))));
+  minWidth := TWNafUtilities.GetWindowSize(Max(k.BitLength, l.BitLength), 8);
 
-  Q := TWNafUtilities.MapPointWithPrecomp(p, width, true, pointMapQ);
-  infoP := TWNafUtilities.GetWNafPreCompInfo(p);
-  infoQ := TWNafUtilities.GetWNafPreCompInfo(Q);
+  infoP := TWNafUtilities.Precompute(p, minWidth, true);
+  q := TEndoUtilities.MapPoint(endomorphism, p);
+  infoQ := TWNafUtilities.PrecomputeWithPointMap(q, endomorphism.pointMap,
+    infoP, true);
+
+  widthP := Min(8, infoP.width);
+  widthQ := Min(8, infoQ.width);
 
   case negK of
     true:
@@ -443,8 +388,8 @@ begin
       preCompNegQ := infoQ.PreCompNeg
   end;
 
-  wnafP := TWNafUtilities.GenerateWindowNaf(width, LK);
-  wnafQ := TWNafUtilities.GenerateWindowNaf(width, LL);
+  wnafP := TWNafUtilities.GenerateWindowNaf(widthP, LK);
+  wnafQ := TWNafUtilities.GenerateWindowNaf(widthQ, LL);
 
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
     preCompNegQ, wnafQ);
@@ -457,29 +402,48 @@ begin
 end;
 
 class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint;
-  const k: TBigInteger; const Q: IECPoint; const l: TBigInteger): IECPoint;
+  const k: TBigInteger; const q: IECPoint; const l: TBigInteger): IECPoint;
 var
   negK, negL: Boolean;
-  widthP, widthQ: Int32;
+  minWidthP, minWidthQ, widthP, widthQ, combSize: Int32;
   infoP, infoQ: IWNafPreCompInfo;
   preCompP, preCompQ, preCompNegP, preCompNegQ
     : TCryptoLibGenericArray<IECPoint>;
   wnafP, wnafQ: TCryptoLibByteArray;
-  LK, LL: TBigInteger;
+  kAbs, lAbs: TBigInteger;
+  c: IECCurve;
 begin
-  LK := k;
-  LL := l;
-  negK := LK.SignValue < 0;
-  negL := LL.SignValue < 0;
 
-  LK := LK.Abs();
-  LL := LL.Abs();
+  negK := k.SignValue < 0;
+  negL := l.SignValue < 0;
+
+  kAbs := k.Abs();
+  lAbs := l.Abs();
 
-  widthP := Max(2, Min(16, TWNafUtilities.GetWindowSize(LK.BitLength)));
-  widthQ := Max(2, Min(16, TWNafUtilities.GetWindowSize(LL.BitLength)));
+  minWidthP := TWNafUtilities.GetWindowSize(kAbs.BitLength, 8);
+  minWidthQ := TWNafUtilities.GetWindowSize(lAbs.BitLength, 8);
 
-  infoP := TWNafUtilities.Precompute(p, widthP, true);
-  infoQ := TWNafUtilities.Precompute(Q, widthQ, true);
+  infoP := TWNafUtilities.Precompute(p, minWidthP, true);
+  infoQ := TWNafUtilities.Precompute(q, minWidthQ, true);
+
+  // When P, Q are 'promoted' (i.e. reused several times), switch to fixed-point algorithm
+
+  c := p.Curve;
+  combSize := TFixedPointUtilities.GetCombSize(c);
+  if ((not negK) and (not negL) and (k.BitLength <= combSize) and
+    (l.BitLength <= combSize) and (infoP.IsPromoted) and (infoQ.IsPromoted))
+  then
+  begin
+    result := ImplShamirsTrickFixedPoint(p, k, q, l);
+    infoP.PreComp := Nil; // Review
+    infoP.PreCompNeg := Nil; // Review
+    infoQ.PreComp := Nil; // Review
+    infoQ.PreCompNeg := Nil; // Review
+    Exit;
+  end;
+
+  widthP := Min(8, infoP.width);
+  widthQ := Min(8, infoQ.width);
 
   if negK then
   begin
@@ -517,8 +481,8 @@ begin
     preCompNegQ := infoQ.PreCompNeg
   end;
 
-  wnafP := TWNafUtilities.GenerateWindowNaf(widthP, LK);
-  wnafQ := TWNafUtilities.GenerateWindowNaf(widthQ, LL);
+  wnafP := TWNafUtilities.GenerateWindowNaf(widthP, kAbs);
+  wnafQ := TWNafUtilities.GenerateWindowNaf(widthQ, lAbs);
 
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
     preCompNegQ, wnafQ);
@@ -536,15 +500,15 @@ class function TECAlgorithms.ImplShamirsTrickWNaf(const preCompP,
 var
   len, zeroes, i, wiP, wiQ, nP, nQ: Int32;
   Curve: IECCurve;
-  infinity, R, point: IECPoint;
+  Infinity, R, point: IECPoint;
   tableP, tableQ: TCryptoLibGenericArray<IECPoint>;
 begin
-  len := Math.Max(System.length(wnafP), System.length(wnafQ));
+  len := Max(System.length(wnafP), System.length(wnafQ));
 
   Curve := preCompP[0].Curve;
-  infinity := Curve.infinity;
+  Infinity := Curve.Infinity;
 
-  R := infinity;
+  R := Infinity;
   zeroes := 0;
 
   i := len - 1;
@@ -576,7 +540,7 @@ begin
       continue;
     end;
 
-    point := infinity;
+    point := Infinity;
     if (wiP <> 0) then
     begin
       nP := System.Abs(wiP);
@@ -626,17 +590,19 @@ begin
   result := R;
 end;
 
-class function TECAlgorithms.ImplSumOfMultiplies
-  (const ps: TCryptoLibGenericArray<IECPoint>; const pointMap: IECPointMap;
+class function TECAlgorithms.ImplSumOfMultiplies(const endomorphism
+  : IECEndomorphism; const ps: TCryptoLibGenericArray<IECPoint>;
   const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint;
 var
   halfCount, fullCount: Int32;
   negs: TCryptoLibBooleanArray;
   infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
+  infoP, infoQ: IWNafPreCompInfo;
   wnafs: TCryptoLibMatrixByteArray;
-  i, j0, j1, width: Int32;
+  i, j0, j1, minWidth, widthP, widthQ: Int32;
   kj0, kj1: TBigInteger;
-  p, Q: IECPoint;
+  p, q: IECPoint;
+  pointMap: IECPointMap;
 begin
   halfCount := System.length(ps);
   fullCount := halfCount shl 1;
@@ -644,6 +610,8 @@ begin
   System.SetLength(infos, fullCount);
   System.SetLength(wnafs, fullCount);
 
+  pointMap := endomorphism.pointMap;
+
   for i := 0 to System.Pred(halfCount) do
   begin
     j0 := i shl 1;
@@ -656,15 +624,21 @@ begin
     negs[j1] := kj1.SignValue < 0;
     kj1 := kj1.Abs();
 
-    width := Max(2, Min(16, TWNafUtilities.GetWindowSize(Max(kj0.BitLength,
-      kj1.BitLength))));
+    minWidth := TWNafUtilities.GetWindowSize
+      (Max(kj0.BitLength, kj1.BitLength), 8);
 
     p := ps[i];
-    Q := TWNafUtilities.MapPointWithPrecomp(p, width, true, pointMap);
-    infos[j0] := TWNafUtilities.GetWNafPreCompInfo(p);
-    infos[j1] := TWNafUtilities.GetWNafPreCompInfo(Q);
-    wnafs[j0] := TWNafUtilities.GenerateWindowNaf(width, kj0);
-    wnafs[j1] := TWNafUtilities.GenerateWindowNaf(width, kj1);
+    infoP := TWNafUtilities.Precompute(p, minWidth, true);
+    q := TEndoUtilities.MapPoint(endomorphism, p);
+    infoQ := TWNafUtilities.PrecomputeWithPointMap(q, pointMap, infoP, true);
+
+    widthP := Min(8, infoP.width);
+    widthQ := Min(8, infoQ.width);
+
+    infos[j0] := infoP;
+    infos[j1] := infoQ;
+    wnafs[j0] := TWNafUtilities.GenerateWindowNaf(widthP, kj0);
+    wnafs[j1] := TWNafUtilities.GenerateWindowNaf(widthQ, kj1);
   end;
 
   result := ImplSumOfMultiplies(negs, infos, wnafs);
@@ -681,8 +655,9 @@ class function TECAlgorithms.ImplSumOfMultiplies
   (const ps: TCryptoLibGenericArray<IECPoint>;
   const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint;
 var
-  count, i, width: Int32;
+  count, i, width, minWidth: Int32;
   negs: TCryptoLibBooleanArray;
+  info: IWNafPreCompInfo;
   infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
   wnafs: TCryptoLibMatrixByteArray;
   ki: TBigInteger;
@@ -700,8 +675,11 @@ begin
     negs[i] := ki.SignValue < 0;
     ki := ki.Abs();
 
-    width := Max(2, Min(16, TWNafUtilities.GetWindowSize(ki.BitLength)));
-    infos[i] := TWNafUtilities.Precompute(ps[i], width, true);
+    minWidth := TWNafUtilities.GetWindowSize(ki.BitLength, 8);
+    info := TWNafUtilities.Precompute(ps[i], minWidth, true);
+    width := Min(8, info.width);
+
+    infos[i] := info;
     wnafs[i] := TWNafUtilities.GenerateWindowNaf(width, ki);
   end;
 
@@ -721,9 +699,9 @@ class function TECAlgorithms.ImplSumOfMultiplies
   const wnafs: TCryptoLibMatrixByteArray): IECPoint;
 var
   len, count, zeroes: Int32;
-  i, J, wi, n: Int32;
+  i, j, wi, n: Int32;
   Curve: IECCurve;
-  infinity, R, point: IECPoint;
+  Infinity, R, point: IECPoint;
   wnaf: TCryptoLibByteArray;
   info: IWNafPreCompInfo;
   table: TCryptoLibGenericArray<IECPoint>;
@@ -737,19 +715,19 @@ begin
   end;
 
   Curve := infos[0].PreComp[0].Curve;
-  infinity := Curve.infinity;
+  Infinity := Curve.Infinity;
 
-  R := infinity;
+  R := Infinity;
   zeroes := 0;
 
   i := len - 1;
   while (i >= 0) do
   begin
-    point := infinity;
+    point := Infinity;
 
-    for J := 0 to System.Pred(count) do
+    for j := 0 to System.Pred(count) do
     begin
-      wnaf := wnafs[J];
+      wnaf := wnafs[j];
       if i < System.length(wnaf) then
       begin
         wi := Int32(ShortInt(wnaf[i]));
@@ -762,8 +740,8 @@ begin
       if (wi <> 0) then
       begin
         n := System.Abs(wi);
-        info := infos[J];
-        if (wi < 0 = negs[J]) then
+        info := infos[j];
+        if (wi < 0 = negs[j]) then
         begin
           table := info.PreComp;
         end
@@ -776,7 +754,7 @@ begin
       end;
     end;
 
-    if (point = infinity) then
+    if (point = Infinity) then
     begin
       System.Inc(zeroes);
       System.Dec(i);
@@ -809,11 +787,10 @@ class function TECAlgorithms.ImplSumOfMultipliesGlv
   const glvEndomorphism: IGlvEndomorphism): IECPoint;
 var
   n: TBigInteger;
-  len, i, J: Int32;
+  len, i, j: Int32;
   &abs, ab: TCryptoLibGenericArray<TBigInteger>;
-  pointMap: IECPointMap;
   pqs: TCryptoLibGenericArray<IECPoint>;
-  p, Q: IECPoint;
+  p, q: IECPoint;
 begin
   n := ps[0].Curve.Order;
 
@@ -822,40 +799,39 @@ begin
   System.SetLength(Abs, len shl 1);
 
   i := 0;
-  J := 0;
+  j := 0;
 
   while (i < len) do
   begin
     ab := glvEndomorphism.DecomposeScalar(ks[i].&Mod(n));
 
-    Abs[J] := ab[0];
-    System.Inc(J);
-    Abs[J] := ab[1];
-    System.Inc(J);
+    Abs[j] := ab[0];
+    System.Inc(j);
+    Abs[j] := ab[1];
+    System.Inc(j);
     System.Inc(i);
   end;
 
-  pointMap := glvEndomorphism.pointMap;
   if (glvEndomorphism.HasEfficientPointMap) then
   begin
-    result := TECAlgorithms.ImplSumOfMultiplies(ps, pointMap, Abs);
+    result := TECAlgorithms.ImplSumOfMultiplies(glvEndomorphism, ps, Abs);
     Exit;
   end;
 
   System.SetLength(pqs, len shl 1);
 
   i := 0;
-  J := 0;
+  j := 0;
 
   while (i < len) do
   begin
     p := ps[i];
-    Q := pointMap.Map(p);
+    q := TEndoUtilities.MapPoint(glvEndomorphism, p);
 
-    pqs[J] := p;
-    System.Inc(J);
-    pqs[J] := Q;
-    System.Inc(J);
+    pqs[j] := p;
+    System.Inc(j);
+    pqs[j] := q;
+    System.Inc(j);
     System.Inc(i);
   end;
 
@@ -903,7 +879,7 @@ class procedure TECAlgorithms.MontgomeryTrick
   const scale: IECFieldElement);
 var
   c: TCryptoLibGenericArray<IECFieldElement>;
-  i, J: Int32;
+  i, j: Int32;
   u, tmp: IECFieldElement;
 begin
   // /*
@@ -935,10 +911,10 @@ begin
 
   while (i > 0) do
   begin
-    J := off + i;
+    j := off + i;
     System.Dec(i);
-    tmp := zs[J];
-    zs[J] := c[i].Multiply(u);
+    tmp := zs[j];
+    zs[j] := c[i].Multiply(u);
     u := u.Multiply(tmp);
   end;
 
@@ -955,18 +931,18 @@ class function TECAlgorithms.ReferenceMultiply(const p: IECPoint;
   const k: TBigInteger): IECPoint;
 var
   x: TBigInteger;
-  Q, LP: IECPoint;
+  q, LP: IECPoint;
   t, i: Int32;
 begin
   LP := p;
   x := k.Abs();
-  Q := LP.Curve.infinity;
+  q := LP.Curve.Infinity;
   t := x.BitLength;
   if (t > 0) then
   begin
     if (x.TestBit(0)) then
     begin
-      Q := LP;
+      q := LP;
     end;
     i := 1;
     while (i < t) do
@@ -974,7 +950,7 @@ begin
       LP := LP.Twice();
       if (x.TestBit(i)) then
       begin
-        Q := Q.Add(LP);
+        q := q.Add(LP);
       end;
       System.Inc(i);
     end;
@@ -983,23 +959,23 @@ begin
 
   if k.SignValue < 0 then
   begin
-    result := Q.Negate();
+    result := q.Negate();
   end
   else
   begin
-    result := Q;
+    result := q;
   end;
 
 end;
 
 class function TECAlgorithms.ShamirsTrick(const p: IECPoint;
-  const k: TBigInteger; const Q: IECPoint; const l: TBigInteger): IECPoint;
+  const k: TBigInteger; const q: IECPoint; const l: TBigInteger): IECPoint;
 var
   cp: IECCurve;
   LQ: IECPoint;
 begin
   cp := p.Curve;
-  LQ := Q;
+  LQ := q;
   LQ := ImportPoint(cp, LQ);
 
   result := ImplCheckResult(ImplShamirsTrickJsf(p, k, LQ, l));
@@ -1060,7 +1036,7 @@ begin
 end;
 
 class function TECAlgorithms.SumOfTwoMultiplies(const p: IECPoint;
-  const a: TBigInteger; const Q: IECPoint; const b: TBigInteger): IECPoint;
+  const a: TBigInteger; const q: IECPoint; const b: TBigInteger): IECPoint;
 var
   cp: IECCurve;
   f2mCurve: IAbstractF2mCurve;
@@ -1068,7 +1044,7 @@ var
   LQ: IECPoint;
 begin
   cp := p.Curve;
-  LQ := Q;
+  LQ := q;
   LQ := ImportPoint(cp, LQ);
 
   // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
@@ -1090,711 +1066,4 @@ begin
   result := ImplCheckResult(ImplShamirsTrickWNaf(p, a, LQ, b));
 end;
 
-{ TWNafUtilities }
-
-class function TWNafUtilities.ResizeTable
-  (const a: TCryptoLibGenericArray<IECPoint>; length: Int32)
-  : TCryptoLibGenericArray<IECPoint>;
-begin
-  result := System.Copy(a);
-  System.SetLength(result, length);
-end;
-
-class function TWNafUtilities.Trim(const a: TCryptoLibInt32Array; length: Int32)
-  : TCryptoLibInt32Array;
-begin
-  result := System.Copy(a, 0, length);
-end;
-
-class function TWNafUtilities.Trim(const a: TCryptoLibByteArray; length: Int32)
-  : TCryptoLibByteArray;
-begin
-  result := System.Copy(a, 0, length);
-end;
-
-class function TWNafUtilities.CheckTable(const table
-  : TCryptoLibGenericArray<IECPoint>; reqLen: Int32): Boolean;
-begin
-  result := (table <> Nil) and (System.length(table) >= reqLen);
-end;
-
-class procedure TWNafUtilities.Boot;
-begin
-  FEMPTY_BYTES := Nil;
-  FEMPTY_INTS := Nil;
-end;
-
-class constructor TWNafUtilities.CreateWNafUtilities;
-begin
-  TWNafUtilities.Boot;
-end;
-
-class function TWNafUtilities.CheckExisting(const existingWNaf
-  : IWNafPreCompInfo; reqPreCompLen: Int32; includeNegated: Boolean): Boolean;
-begin
-  result := (existingWNaf <> Nil) and CheckTable(existingWNaf.PreComp,
-    reqPreCompLen) and ((not includeNegated) or
-    CheckTable(existingWNaf.PreCompNeg, reqPreCompLen));
-end;
-
-class function TWNafUtilities.GenerateCompactNaf(const k: TBigInteger)
-  : TCryptoLibInt32Array;
-var
-  _3k, diff: TBigInteger;
-  bits, highBit, &length, zeroes, i, digit: Int32;
-  naf: TCryptoLibInt32Array;
-begin
-  if ((TBits.Asr32(k.BitLength, 16)) <> 0) then
-  begin
-    raise EArgumentCryptoLibException.CreateRes(@SInvalidBitLength);
-  end;
-  if (k.SignValue = 0) then
-  begin
-    result := FEMPTY_INTS;
-    Exit;
-  end;
-
-  _3k := k.ShiftLeft(1).Add(k);
-
-  bits := _3k.BitLength;
-  System.SetLength(naf, TBits.Asr32(bits, 1));
-
-  diff := _3k.&Xor(k);
-
-  highBit := bits - 1;
-  &length := 0;
-  zeroes := 0;
-
-  i := 1;
-
-  while (i < highBit) do
-  begin
-    if (not diff.TestBit(i)) then
-    begin
-      System.Inc(zeroes);
-      System.Inc(i);
-      continue;
-    end;
-
-    if k.TestBit(i) then
-    begin
-      digit := -1;
-    end
-    else
-    begin
-      digit := 1;
-    end;
-
-    naf[length] := (digit shl 16) or zeroes;
-    System.Inc(length);
-    zeroes := 1;
-
-    System.Inc(i, 2);
-
-  end;
-
-  naf[length] := (1 shl 16) or zeroes;
-  System.Inc(length);
-
-  if (System.length(naf) > length) then
-  begin
-    naf := Trim(naf, length);
-  end;
-
-  result := naf;
-end;
-
-class function TWNafUtilities.GenerateCompactWindowNaf(width: Int32;
-  const k: TBigInteger): TCryptoLibInt32Array;
-var
-  wnaf: TCryptoLibInt32Array;
-  pow2, mask, sign, &length, &pos, digit, zeroes: Int32;
-  carry: Boolean;
-  LK: TBigInteger;
-begin
-  LK := k;
-  if (width = 2) then
-  begin
-    result := GenerateCompactNaf(LK);
-    Exit;
-  end;
-
-  if ((width < 2) or (width > 16)) then
-  begin
-    raise EArgumentCryptoLibException.CreateRes(@SInvalidRange);
-  end;
-  if ((TBits.Asr32(LK.BitLength, 16)) <> 0) then
-  begin
-    raise EArgumentCryptoLibException.CreateRes(@SInvalidBitLength);
-  end;
-  if (LK.SignValue = 0) then
-  begin
-    result := FEMPTY_INTS;
-    Exit;
-  end;
-
-  System.SetLength(wnaf, (LK.BitLength div width) + 1);
-
-  // 2^width and a mask and sign bit set accordingly
-  pow2 := 1 shl width;
-  mask := pow2 - 1;
-  sign := TBits.Asr32(pow2, 1);
-
-  carry := false;
-  length := 0;
-  pos := 0;
-
-  while (pos <= LK.BitLength) do
-  begin
-    if (LK.TestBit(pos) = carry) then
-    begin
-      System.Inc(pos);
-      continue;
-    end;
-
-    LK := LK.ShiftRight(pos);
-
-    digit := LK.Int32Value and mask;
-    if (carry) then
-    begin
-      System.Inc(digit);
-    end;
-
-    carry := (digit and sign) <> 0;
-    if (carry) then
-    begin
-      digit := digit - pow2;
-    end;
-
-    if length > 0 then
-    begin
-      zeroes := pos - 1;
-    end
-    else
-    begin
-      zeroes := pos;
-    end;
-
-    wnaf[length] := (digit shl 16) or zeroes;
-    System.Inc(length);
-    pos := width;
-  end;
-
-  // Reduce the WNAF array to its actual length
-  if (System.length(wnaf) > length) then
-  begin
-    wnaf := Trim(wnaf, length);
-  end;
-
-  result := wnaf;
-end;
-
-class function TWNafUtilities.GenerateJsf(const g, h: TBigInteger)
-  : TCryptoLibByteArray;
-var
-  digits, J, d0, d1, offset, n0, n1, u0, u1: Int32;
-  jsf: TCryptoLibByteArray;
-  k0, k1: TBigInteger;
-begin
-  digits := Max(g.BitLength, h.BitLength) + 1;
-
-  System.SetLength(jsf, digits);
-
-  k0 := g;
-  k1 := h;
-  J := 0;
-  d0 := 0;
-  d1 := 0;
-
-  offset := 0;
-
-  while (((d0 or d1) <> 0) or (k0.BitLength > offset) or
-    (k1.BitLength > offset)) do
-  begin
-    n0 := (Int32(UInt32(k0.Int32Value) shr offset) + d0) and 7;
-    n1 := (Int32(UInt32(k1.Int32Value) shr offset) + d1) and 7;
-
-    u0 := n0 and 1;
-    if (u0 <> 0) then
-    begin
-      u0 := u0 - (n0 and 2);
-      if (((n0 + u0) = 4) and ((n1 and 3) = 2)) then
-      begin
-        u0 := -u0;
-      end;
-    end;
-
-    u1 := n1 and 1;
-    if (u1 <> 0) then
-    begin
-      u1 := u1 - (n1 and 2);
-      if (((n1 + u1) = 4) and ((n0 and 3) = 2)) then
-      begin
-        u1 := -u1;
-      end;
-    end;
-
-    if ((d0 shl 1) = (1 + u0)) then
-    begin
-      d0 := d0 xor 1;
-    end;
-    if ((d1 shl 1) = (1 + u1)) then
-    begin
-      d1 := d1 xor 1;
-    end;
-
-    System.Inc(offset);
-    if (offset = 30) then
-    begin
-      offset := 0;
-      k0 := k0.ShiftRight(30);
-      k1 := k1.ShiftRight(30);
-    end;
-
-    jsf[J] := Byte((u0 shl 4) or (u1 and $F));
-    System.Inc(J);
-  end;
-
-  // Reduce the JSF array to its actual length
-  if (System.length(jsf) > J) then
-  begin
-    jsf := Trim(jsf, J);
-  end;
-
-  result := jsf;
-end;
-
-class function TWNafUtilities.GenerateNaf(const k: TBigInteger)
-  : TCryptoLibByteArray;
-var
-  _3k, diff: TBigInteger;
-  digits, i: Int32;
-  naf: TCryptoLibByteArray;
-begin
-  if (k.SignValue = 0) then
-  begin
-    result := FEMPTY_BYTES;
-    Exit;
-  end;
-
-  _3k := k.ShiftLeft(1).Add(k);
-
-  digits := _3k.BitLength - 1;
-  System.SetLength(naf, digits);
-
-  diff := _3k.&Xor(k);
-
-  i := 1;
-
-  while i < digits do
-  begin
-    if (diff.TestBit(i)) then
-    begin
-      if k.TestBit(i) then
-      begin
-        naf[i - 1] := Byte(-1);
-      end
-      else
-      begin
-        naf[i - 1] := Byte(1);
-      end;
-
-      System.Inc(i);
-    end;
-    System.Inc(i);
-  end;
-
-  naf[digits - 1] := 1;
-
-  result := naf;
-end;
-
-class function TWNafUtilities.GenerateWindowNaf(width: Int32;
-  const k: TBigInteger): TCryptoLibByteArray;
-var
-  wnaf: TCryptoLibByteArray;
-  pow2, mask, sign, &length, &pos, digit: Int32;
-  carry: Boolean;
-  LK: TBigInteger;
-begin
-  LK := k;
-  if (width = 2) then
-  begin
-    result := GenerateNaf(LK);
-    Exit;
-  end;
-
-  if ((width < 2) or (width > 8)) then
-  begin
-    raise EArgumentCryptoLibException.CreateRes(@SInvalidRange2);
-  end;
-  if (LK.SignValue = 0) then
-  begin
-    result := FEMPTY_BYTES;
-    Exit;
-  end;
-
-  System.SetLength(wnaf, LK.BitLength + 1);
-
-  // 2^width and a mask and sign bit set accordingly
-  pow2 := 1 shl width;
-  mask := pow2 - 1;
-  sign := TBits.Asr32(pow2, 1);
-
-  carry := false;
-  length := 0;
-  pos := 0;
-
-  while (pos <= LK.BitLength) do
-  begin
-    if (LK.TestBit(pos) = carry) then
-    begin
-      System.Inc(pos);
-      continue;
-    end;
-
-    LK := LK.ShiftRight(pos);
-
-    digit := LK.Int32Value and mask;
-    if (carry) then
-    begin
-      System.Inc(digit);
-    end;
-
-    carry := (digit and sign) <> 0;
-    if (carry) then
-    begin
-      digit := digit - pow2;
-    end;
-
-    if length > 0 then
-    begin
-      length := length + (pos - 1);
-    end
-    else
-    begin
-      length := length + (pos);
-    end;
-
-    wnaf[length] := Byte(digit);
-    System.Inc(length);
-    pos := width;
-  end;
-
-  // Reduce the WNAF array to its actual length
-  if (System.length(wnaf) > length) then
-  begin
-    wnaf := Trim(wnaf, length);
-  end;
-
-  result := wnaf;
-end;
-
-class function TWNafUtilities.GetNafWeight(const k: TBigInteger): Int32;
-var
-  _3k, diff: TBigInteger;
-begin
-  if (k.SignValue = 0) then
-  begin
-    result := 0;
-    Exit;
-  end;
-
-  _3k := k.ShiftLeft(1).Add(k);
-  diff := _3k.&Xor(k);
-
-  result := diff.BitCount;
-end;
-
-class function TWNafUtilities.GetWindowSize(bits: Int32;
-  const windowSizeCutoffs: array of Int32): Int32;
-var
-  w: Int32;
-begin
-  w := 0;
-  while (w < System.length(windowSizeCutoffs)) do
-  begin
-    if (bits < windowSizeCutoffs[w]) then
-    begin
-      break;
-    end;
-    System.Inc(w);
-  end;
-
-  result := w + 2;
-end;
-
-class function TWNafUtilities.GetWindowSize(bits: Int32): Int32;
-begin
-  result := GetWindowSize(bits, FDEFAULT_WINDOW_SIZE_CUTOFFS);
-end;
-
-class function TWNafUtilities.GetWNafPreCompInfo(const preCompInfo
-  : IPreCompInfo): IWNafPreCompInfo;
-begin
-  result := preCompInfo as IWNafPreCompInfo;
-end;
-
-class function TWNafUtilities.GetWNafPreCompInfo(const p: IECPoint)
-  : IWNafPreCompInfo;
-var
-  preCompInfo: IPreCompInfo;
-begin
-  preCompInfo := p.Curve.GetPreCompInfo(p, PRECOMP_NAME);
-  result := GetWNafPreCompInfo(preCompInfo);
-end;
-
-class function TWNafUtilities.MapPointWithPrecomp(const p: IECPoint;
-  width: Int32; includeNegated: Boolean; const pointMap: IECPointMap): IECPoint;
-var
-  c: IECCurve;
-  wnafPreCompP: IWNafPreCompInfo;
-  Q: IECPoint;
-begin
-  c := p.Curve;
-
-  wnafPreCompP := Precompute(p, width, includeNegated);
-
-  Q := pointMap.Map(p);
-
-  c.Precompute(Q, PRECOMP_NAME, TMapPointCallback.Create(wnafPreCompP,
-    includeNegated, pointMap) as IMapPointCallback);
-
-  result := Q;
-
-end;
-
-class function TWNafUtilities.Precompute(const p: IECPoint; width: Int32;
-  includeNegated: Boolean): IWNafPreCompInfo;
-begin
-  result := p.Curve.Precompute(p, PRECOMP_NAME, TWNafCallback.Create(p, width,
-    includeNegated) as IWNafCallback) as IWNafPreCompInfo;
-end;
-
-{ TWNafUtilities.TMapPointCallback }
-
-constructor TWNafUtilities.TMapPointCallback.Create(const wnafPreCompP
-  : IWNafPreCompInfo; includeNegated: Boolean; const pointMap: IECPointMap);
-begin
-  Inherited Create();
-  Fm_wnafPreCompP := wnafPreCompP;
-  Fm_includeNegated := includeNegated;
-  Fm_pointMap := pointMap;
-end;
-
-function TWNafUtilities.TMapPointCallback.Precompute(const existing
-  : IPreCompInfo): IPreCompInfo;
-var
-  tempResult: IWNafPreCompInfo;
-  twiceP, twiceQ: IECPoint;
-  preCompP, preCompQ, preCompNegQ: TCryptoLibGenericArray<IECPoint>;
-  i: Int32;
-begin
-  tempResult := TWNafPreCompInfo.Create();
-
-  twiceP := Fm_wnafPreCompP.Twice;
-  if (twiceP <> Nil) then
-  begin
-    twiceQ := Fm_pointMap.Map(twiceP);
-    tempResult.Twice := twiceQ;
-  end;
-
-  preCompP := Fm_wnafPreCompP.PreComp;
-
-  System.SetLength(preCompQ, System.length(preCompP));
-  for i := 0 to System.Pred(System.length(preCompP)) do
-  begin
-    preCompQ[i] := Fm_pointMap.Map(preCompP[i]);
-  end;
-
-  tempResult.PreComp := preCompQ;
-
-  if (Fm_includeNegated) then
-  begin
-
-    System.SetLength(preCompNegQ, System.length(preCompQ));
-
-    for i := 0 to System.Pred(System.length(preCompNegQ)) do
-    begin
-      preCompNegQ[i] := preCompQ[i].Negate();
-    end;
-
-    tempResult.PreCompNeg := preCompNegQ;
-  end;
-
-  result := tempResult;
-end;
-
-{ TWNafUtilities.TWNafCallback }
-
-constructor TWNafUtilities.TWNafCallback.Create(const p: IECPoint; width: Int32;
-  includeNegated: Boolean);
-begin
-  Inherited Create();
-  Fm_p := p;
-  Fm_width := width;
-  Fm_includeNegated := includeNegated;
-end;
-
-function TWNafUtilities.TWNafCallback.Precompute(const existing: IPreCompInfo)
-  : IPreCompInfo;
-var
-  twiceP, isoTwiceP, last: IECPoint;
-  c: IECCurve;
-  PreComp, PreCompNeg, EMPTY_POINTS: TCryptoLibGenericArray<IECPoint>;
-  tempRes, existingWNaf: IWNafPreCompInfo;
-  reqPreCompLen, iniPreCompLen, curPreCompLen, pos: Int32;
-  iso, iso2, iso3: IECFieldElement;
-begin
-  EMPTY_POINTS := Nil;
-  existingWNaf := existing as IWNafPreCompInfo;
-
-  reqPreCompLen := 1 shl Max(0, Fm_width - 2);
-
-  if (CheckExisting(existingWNaf, reqPreCompLen, Fm_includeNegated)) then
-  begin
-    result := existingWNaf;
-    Exit;
-  end;
-
-  c := Fm_p.Curve;
-
-  if (existingWNaf <> Nil) then
-  begin
-    PreComp := existingWNaf.PreComp;
-    PreCompNeg := existingWNaf.PreCompNeg;
-    twiceP := existingWNaf.Twice;
-  end;
-
-  iniPreCompLen := 0;
-  if (PreComp = Nil) then
-  begin
-    PreComp := EMPTY_POINTS;
-  end
-  else
-  begin
-    iniPreCompLen := System.length(PreComp);
-  end;
-
-  if (iniPreCompLen < reqPreCompLen) then
-  begin
-    PreComp := TWNafUtilities.ResizeTable(PreComp, reqPreCompLen);
-
-    if (reqPreCompLen = 1) then
-    begin
-      PreComp[0] := Fm_p.Normalize();
-    end
-    else
-    begin
-      curPreCompLen := iniPreCompLen;
-      if (curPreCompLen = 0) then
-      begin
-        PreComp[0] := Fm_p;
-        curPreCompLen := 1;
-      end;
-
-      if (reqPreCompLen = 2) then
-      begin
-        PreComp[1] := Fm_p.threeTimes();
-      end
-      else
-      begin
-        isoTwiceP := twiceP;
-        last := PreComp[curPreCompLen - 1];
-        if (isoTwiceP = Nil) then
-        begin
-          isoTwiceP := PreComp[0].Twice();
-          twiceP := isoTwiceP;
-          //
-          // /*
-          // * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism
-          // * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This
-          // * also requires scaling the initial point's X, Y coordinates, and reversing the
-          // * isomorphism as part of the subsequent normalization.
-          // *
-          // *  NOTE: The correctness of this optimization depends on:
-          // *      1) additions do not use the curve's A, B coefficients.
-          // *      2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...
-          // */
-          if ((not(twiceP.IsInfinity)) and (TECAlgorithms.IsFpCurve(c)) and
-            (c.FieldSize >= 64)) then
-          begin
-            case (c.CoordinateSystem) of
-              TECCurveConstants.COORD_JACOBIAN,
-                TECCurveConstants.COORD_JACOBIAN_CHUDNOVSKY,
-                TECCurveConstants.COORD_JACOBIAN_MODIFIED:
-
-                begin
-                  iso := twiceP.GetZCoord(0);
-                  isoTwiceP := c.CreatePoint(twiceP.XCoord.ToBigInteger,
-                    twiceP.YCoord.ToBigInteger());
-
-                  iso2 := iso.square();
-                  iso3 := iso2.Multiply(iso);
-                  last := last.scaleX(iso2).scaleY(iso3);
-
-                  if (iniPreCompLen = 0) then
-                  begin
-                    PreComp[0] := last;
-                  end;
-                end;
-
-            end;
-
-          end;
-        end;
-
-        while (curPreCompLen < reqPreCompLen) do
-        begin
-          // /*
-          // * Compute the new ECPoints for the precomputation array. The values 1, 3,
-          // * 5, ..., 2^(width-1)-1 times p are computed
-          // */
-          last := last.Add(isoTwiceP);
-          PreComp[curPreCompLen] := last;
-          System.Inc(curPreCompLen);
-        end;
-      end;
-      //
-      // /*
-      // * Having oft-used operands in affine form makes operations faster.
-      // */
-      c.NormalizeAll(PreComp, iniPreCompLen,
-        reqPreCompLen - iniPreCompLen, iso);
-    end;
-  end;
-
-  if (Fm_includeNegated) then
-  begin
-
-    if (PreCompNeg = Nil) then
-    begin
-      pos := 0;
-      System.SetLength(PreCompNeg, reqPreCompLen);
-
-    end
-    else
-    begin
-      pos := System.length(PreCompNeg);
-      if (pos < reqPreCompLen) then
-      begin
-        PreCompNeg := TWNafUtilities.ResizeTable(PreCompNeg, reqPreCompLen);
-      end;
-    end;
-
-    while (pos < reqPreCompLen) do
-    begin
-      PreCompNeg[pos] := PreComp[pos].Negate();
-      System.Inc(pos);
-    end;
-  end;
-
-  tempRes := TWNafPreCompInfo.Create();
-  tempRes.PreComp := PreComp;
-  tempRes.PreCompNeg := PreCompNeg;
-  tempRes.Twice := twiceP;
-
-  result := tempRes;
-end;
-
 end.

+ 311 - 72
CryptoLib/src/Math/EC/ClpECC.pas

@@ -37,9 +37,7 @@ uses
   ClpIGlvEndomorphism,
   ClpECAlgorithms,
   ClpLongArray,
-  ClpGlvMultiplier,
-  ClpWNafL2RMultiplier,
-  ClpWTauNafMultiplier,
+  ClpMultipliers,
   ClpFiniteFields,
   ClpSetWeakRef,
   ClpECCurveConstants,
@@ -95,6 +93,7 @@ resourcestring
   SNotProjectiveCoordSystem = 'Not a Projective Coordinate System';
   SCannotBeNegative = 'Cannot be Negative, "e"';
   SNilFieldElement = 'Exactly one of the Field Elements is Nil';
+  SUnsupportedOperation = 'Constant-time Lookup not Supported';
 
 type
   TECFieldElement = class abstract(TInterfacedObject, IECFieldElement)
@@ -260,6 +259,7 @@ type
   public
     function Trace(): Int32; virtual;
     function HalfTrace(): IECFieldElement; virtual;
+    function HasFastTrace(): Boolean; virtual;
 
   end;
 
@@ -691,20 +691,61 @@ type
   end;
 
 type
-  TDefaultLookupTable = class(TInterfacedObject, IDefaultLookupTable,
-    IECLookupTable)
+  TAbstractECLookupTable = class abstract(TInterfacedObject,
+    IAbstractECLookupTable, IECLookupTable)
+
+  strict protected
+    function GetSize: Int32; virtual; abstract;
+
+  public
+    function Lookup(index: Int32): IECPoint; virtual; abstract;
+    function LookupVar(index: Int32): IECPoint; virtual; abstract;
+    property Size: Int32 read GetSize;
+
+  end;
+
+type
+  TSimpleLookupTable = class abstract(TAbstractECLookupTable,
+    ISimpleLookupTable)
+
+  strict private
+  var
+    FPoints: TCryptoLibGenericArray<IECPoint>;
+
+    class function Copy(const points: TCryptoLibGenericArray<IECPoint>;
+      off, len: Int32): TCryptoLibGenericArray<IECPoint>; static;
+
+  strict protected
+    function GetSize: Int32; override;
+
+  public
+    constructor Create(const points: TCryptoLibGenericArray<IECPoint>;
+      off, len: Int32);
+
+    function Lookup(index: Int32): IECPoint; override;
+    function LookupVar(index: Int32): IECPoint; override;
+
+  end;
+
+type
+  TDefaultLookupTable = class(TAbstractECLookupTable, IDefaultLookupTable)
   strict private
   var
     Fm_outer: IECCurve;
     Fm_table: TCryptoLibByteArray;
     Fm_size: Int32;
 
+    function CreatePoint(const x, y: TCryptoLibByteArray): IECPoint;
+
+  strict protected
+    function GetSize: Int32; override;
+
   public
     constructor Create(const outer: IECCurve; const table: TCryptoLibByteArray;
-      size: Int32);
-    function GetSize: Int32; virtual;
-    function Lookup(index: Int32): IECPoint; virtual;
-    property size: Int32 read GetSize;
+      Size: Int32);
+
+    function Lookup(index: Int32): IECPoint; override;
+    function LookupVar(index: Int32): IECPoint; override;
 
   end;
 
@@ -724,20 +765,24 @@ type
   end;
 
 type
-  TDefaultF2mLookupTable = class(TInterfacedObject, IDefaultF2mLookupTable,
-    IECLookupTable)
+  TDefaultF2mLookupTable = class(TAbstractECLookupTable, IDefaultF2mLookupTable)
   strict private
   var
     Fm_outer: IF2mCurve;
     Fm_table: TCryptoLibInt64Array;
     Fm_size: Int32;
 
+    function CreatePoint(const x, y: TCryptoLibInt64Array): IECPoint;
+
+  strict protected
+    function GetSize: Int32; override;
+
   public
     constructor Create(const outer: IF2mCurve;
-      const table: TCryptoLibInt64Array; size: Int32);
-    function GetSize: Int32; virtual;
-    function Lookup(index: Int32): IECPoint; virtual;
-    property size: Int32 read GetSize;
+      const table: TCryptoLibInt64Array; Size: Int32);
+
+    function Lookup(index: Int32): IECPoint; override;
+    function LookupVar(index: Int32): IECPoint; override;
 
   end;
 
@@ -1158,6 +1203,9 @@ type
     function ScaleX(const scale: IECFieldElement): IECPoint; virtual;
     function ScaleY(const scale: IECFieldElement): IECPoint; virtual;
 
+    function ScaleXNegateY(const scale: IECFieldElement): IECPoint; virtual;
+    function ScaleYNegateX(const scale: IECFieldElement): IECPoint; virtual;
+
     function GetEncoded(): TCryptoLibByteArray; overload; virtual;
     function GetEncoded(compressed: Boolean): TCryptoLibByteArray; overload;
       virtual; abstract;
@@ -1400,6 +1448,9 @@ type
     function ScaleX(const scale: IECFieldElement): IECPoint; override;
     function ScaleY(const scale: IECFieldElement): IECPoint; override;
 
+    function ScaleXNegateY(const scale: IECFieldElement): IECPoint; override;
+    function ScaleYNegateX(const scale: IECFieldElement): IECPoint; override;
+
     function Subtract(const b: IECPoint): IECPoint; override;
 
     function Tau(): IAbstractF2mPoint; virtual;
@@ -2433,8 +2484,8 @@ end;
 
 function TAbstractF2mFieldElement.HalfTrace: IECFieldElement;
 var
-  m, i: Int32;
-  fe, ht: IECFieldElement;
+  m, n, K, nk: Int32;
+  ht: IECFieldElement;
 begin
   m := FieldSize;
   if ((m and 1) = 0) then
@@ -2442,34 +2493,53 @@ begin
     raise EArgumentCryptoLibException.CreateRes(@SHalfTraceUndefinedForM);
   end;
 
-  fe := Self as IECFieldElement;
-  ht := fe;
-  i := 2;
-  while i < m do
+  n := TBits.Asr32((m + 1), 1);
+  K := 31 - TBits.NumberOfLeadingZeros(n);
+  nk := 1;
+
+  ht := Self as IECFieldElement;
+  while (K > 0) do
   begin
-    fe := fe.SquarePow(2);
-    ht := ht.Add(fe);
-    System.Inc(i, 2);
-  end;
+    ht := ht.SquarePow(nk shl 1).Add(ht);
+    System.Dec(K);
+    nk := TBits.Asr32(n, K);
 
+    if ((nk and 1) <> 0) then
+    begin
+      ht := ht.SquarePow(2).Add(Self as IECFieldElement);
+    end;
+  end;
   result := ht;
 end;
 
+function TAbstractF2mFieldElement.HasFastTrace: Boolean;
+begin
+  result := false;
+
+end;
+
 function TAbstractF2mFieldElement.Trace: Int32;
 var
-  m, i: Int32;
-  fe, tr: IECFieldElement;
+  m, K, mk: Int32;
+  tr: IECFieldElement;
 begin
   m := FieldSize;
-  fe := Self as IECFieldElement;
-  tr := fe;
 
-  i := 1;
-  while i < m do
+  K := 31 - TBits.NumberOfLeadingZeros(m);
+  mk := 1;
+
+  tr := Self as IECFieldElement;
+  while (K > 0) do
   begin
-    fe := fe.Square();
-    tr := tr.Add(fe);
-    System.Inc(i);
+    tr := tr.SquarePow(mk).Add(tr);
+
+    System.Dec(K);
+    mk := TBits.Asr32(m, K);
+
+    if ((mk and 1) <> 0) then
+    begin
+      tr := tr.Square().Add(Self as IECFieldElement);
+    end;
   end;
 
   if (tr.IsZero) then
@@ -3372,9 +3442,36 @@ end;
 function TAbstractF2mCurve.SolveQuadraticEquation(const beta: IECFieldElement)
   : IECFieldElement;
 var
-  gamma, z, zeroElement, t, w, w2: IECFieldElement;
+  gamma, z, zeroElement, t, w, w2, r: IECFieldElement;
+  betaF2m: IAbstractF2mFieldElement;
   m, i: Int32;
+  fastTrace: Boolean;
 begin
+
+  betaF2m := beta as IAbstractF2mFieldElement;
+
+  fastTrace := betaF2m.HasFastTrace();
+  if ((fastTrace) and (betaF2m.Trace() <> 0)) then
+  begin
+    result := Nil;
+    Exit;
+  end;
+
+  m := FieldSize;
+
+  // For odd m, use the half-trace
+  if ((m and 1) <> 0) then
+  begin
+    r := betaF2m.HalfTrace();
+    if ((fastTrace) or (r.Square().Add(r).Add(beta).IsZero)) then
+    begin
+      result := r;
+      Exit;
+    end;
+    result := Nil;
+    Exit;
+  end;
+
   if (beta.IsZero) then
   begin
     result := beta;
@@ -3603,12 +3700,22 @@ end;
 { TDefaultLookupTable }
 
 constructor TDefaultLookupTable.Create(const outer: IECCurve;
-  const table: TCryptoLibByteArray; size: Int32);
+  const table: TCryptoLibByteArray; Size: Int32);
 begin
   Inherited Create();
   Fm_outer := outer;
   Fm_table := table;
-  Fm_size := size;
+  Fm_size := Size;
+end;
+
+function TDefaultLookupTable.CreatePoint(const x, y: TCryptoLibByteArray)
+  : IECPoint;
+var
+  XFieldElement, YFieldElement: IECFieldElement;
+begin
+  XFieldElement := Fm_outer.FromBigInteger(TBigInteger.Create(1, x));
+  YFieldElement := Fm_outer.FromBigInteger(TBigInteger.Create(1, y));
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
 end;
 
 function TDefaultLookupTable.GetSize: Int32;
@@ -3621,7 +3728,6 @@ var
   FE_BYTES, position, i, j: Int32;
   x, y: TCryptoLibByteArray;
   MASK: Byte;
-  XFieldElement, YFieldElement: IECFieldElement;
 begin
   FE_BYTES := (Fm_outer.FieldSize + 7) div 8;
   System.SetLength(x, FE_BYTES);
@@ -3636,41 +3742,52 @@ begin
 
     for j := 0 to System.Pred(FE_BYTES) do
     begin
-
       x[j] := x[j] xor Byte(Fm_table[position + j] and MASK);
       y[j] := y[j] xor Byte(Fm_table[position + FE_BYTES + j] and MASK);
     end;
     position := position + (FE_BYTES * 2);
   end;
 
-  XFieldElement := Fm_outer.FromBigInteger(TBigInteger.Create(1, x));
-  YFieldElement := Fm_outer.FromBigInteger(TBigInteger.Create(1, y));
-  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
+  result := CreatePoint(x, y);
+end;
+
+function TDefaultLookupTable.LookupVar(index: Int32): IECPoint;
+var
+  FE_BYTES, position, j: Int32;
+  x, y: TCryptoLibByteArray;
+begin
+  FE_BYTES := (Fm_outer.FieldSize + 7) div 8;
+  System.SetLength(x, FE_BYTES);
+  System.SetLength(y, FE_BYTES);
+
+  position := index * FE_BYTES * 2;
+
+  for j := 0 to System.Pred(FE_BYTES) do
+  begin
+    x[j] := Fm_table[position + j];
+    y[j] := Fm_table[position + FE_BYTES + j];
+  end;
+
+  result := CreatePoint(x, y);
 end;
 
 { TDefaultF2mLookupTable }
 
 constructor TDefaultF2mLookupTable.Create(const outer: IF2mCurve;
-  const table: TCryptoLibInt64Array; size: Int32);
+  const table: TCryptoLibInt64Array; Size: Int32);
 begin
   Inherited Create();
   Fm_outer := outer;
   Fm_table := table;
-  Fm_size := size;
-end;
-
-function TDefaultF2mLookupTable.GetSize: Int32;
-begin
-  result := Fm_size;
+  Fm_size := Size;
 end;
 
-function TDefaultF2mLookupTable.Lookup(index: Int32): IECPoint;
+function TDefaultF2mLookupTable.CreatePoint(const x, y: TCryptoLibInt64Array)
+  : IECPoint;
 var
-  FE_LONGS, position, m, i, j: Int32;
-  ks: TCryptoLibInt32Array;
-  x, y: TCryptoLibInt64Array;
-  MASK: Int64;
   XFieldElement, YFieldElement: IECFieldElement;
+  m: Int32;
+  ks: TCryptoLibInt32Array;
 begin
   m := Fm_outer.m;
   if Fm_outer.IsTrinomial() then
@@ -3682,6 +3799,22 @@ begin
     ks := TCryptoLibInt32Array.Create(Fm_outer.k1, Fm_outer.k2, Fm_outer.k3);
   end;
 
+  XFieldElement := TF2mFieldElement.Create(m, ks, TLongArray.Create(x));
+  YFieldElement := TF2mFieldElement.Create(m, ks, TLongArray.Create(y));
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
+end;
+
+function TDefaultF2mLookupTable.GetSize: Int32;
+begin
+  result := Fm_size;
+end;
+
+function TDefaultF2mLookupTable.Lookup(index: Int32): IECPoint;
+var
+  FE_LONGS, position, i, j: Int32;
+  x, y: TCryptoLibInt64Array;
+  MASK: Int64;
+begin
   FE_LONGS := (Fm_outer.m + 63) div 64;
   System.SetLength(x, FE_LONGS);
   System.SetLength(y, FE_LONGS);
@@ -3695,16 +3828,33 @@ begin
 
     for j := 0 to System.Pred(FE_LONGS) do
     begin
-
       x[j] := x[j] xor (Fm_table[position + j] and MASK);
       y[j] := y[j] xor (Fm_table[position + FE_LONGS + j] and MASK);
     end;
     position := position + (FE_LONGS * 2);
   end;
 
-  XFieldElement := TF2mFieldElement.Create(m, ks, TLongArray.Create(x));
-  YFieldElement := TF2mFieldElement.Create(m, ks, TLongArray.Create(y));
-  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
+  result := CreatePoint(x, y);
+end;
+
+function TDefaultF2mLookupTable.LookupVar(index: Int32): IECPoint;
+var
+  FE_LONGS, position, j: Int32;
+  x, y: TCryptoLibInt64Array;
+begin
+  FE_LONGS := (Fm_outer.m + 63) div 64;
+  System.SetLength(x, FE_LONGS);
+  System.SetLength(y, FE_LONGS);
+
+  position := index * FE_LONGS * 2;
+
+  for j := 0 to System.Pred(FE_LONGS) do
+  begin
+    x[j] := Fm_table[position + j];
+    y[j] := Fm_table[position + FE_LONGS + j];
+  end;
+
+  result := CreatePoint(x, y);
 end;
 
 { TECPoint }
@@ -3798,6 +3948,19 @@ begin
   end;
 end;
 
+function TECPoint.ScaleXNegateY(const scale: IECFieldElement): IECPoint;
+begin
+  if IsInfinity then
+  begin
+    result := Self;
+  end
+  else
+  begin
+    result := curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord.Negate,
+      RawZCoords, IsCompressed);
+  end;
+end;
+
 function TECPoint.ScaleY(const scale: IECFieldElement): IECPoint;
 begin
   if IsInfinity then
@@ -3811,6 +3974,19 @@ begin
   end;
 end;
 
+function TECPoint.ScaleYNegateX(const scale: IECFieldElement): IECPoint;
+begin
+  if IsInfinity then
+  begin
+    result := Self;
+  end
+  else
+  begin
+    result := curve.CreateRawPoint(RawXCoord.Negate, RawYCoord.Multiply(scale),
+      RawZCoords, IsCompressed);
+  end;
+end;
+
 procedure TECPoint.SetpreCompTable(const Value
   : TDictionary<String, IPreCompInfo>);
 begin
@@ -6201,21 +6377,23 @@ function TAbstractF2mPoint.SatisfiesOrder: Boolean;
 var
   Cofactor: TBigInteger;
   n: IECPoint;
-  x, rhs, lambda, w, t: IECFieldElement;
+  x, rhs, L, t, y: IECFieldElement;
   Lcurve: IECCurve;
 begin
   Lcurve := curve;
   Cofactor := Lcurve.GetCofactor();
   if (TBigInteger.Two.Equals(Cofactor)) then
   begin
-    // /*
-    // *  Check that the trace of (X + A) is 0, then there exists a solution to L^2 + L = X + A,
-    // *  and so a halving is possible, so this point is the double of another.
-    // */
+    (*
+      * Check that 0 == Tr(X + A); then there exists a solution to L^2 + L = X + A, and
+      * so a halving is possible, so this point is the double of another.
+      *
+      * Note: Tr(A) == 1 for cofactor 2 curves.
+    *)
     n := Normalize();
     x := n.AffineXCoord;
     rhs := x.Add(Lcurve.a);
-    result := (rhs as IAbstractF2mFieldElement).Trace() = 0;
+    result := (x as IAbstractF2mFieldElement).Trace() <> 0;
     Exit;
   end;
   if (TBigInteger.Four.Equals(Cofactor)) then
@@ -6226,21 +6404,33 @@ begin
     // * and check if Tr(w + A) == 0 for at least one; then a second halving is possible
     // * (see comments for cofactor 2 above), so this point is four times another.
     // *
-    // * Note: Tr(x^2) == Tr(x).
+    // * Note: Tr(A) == 0 for cofactor 4 curves.
     // */
     n := Normalize();
     x := n.AffineXCoord;
-    lambda := (Lcurve as IAbstractF2mCurve).SolveQuadraticEquation
-      (x.Add(curve.a));
-    if (lambda = Nil) then
+    L := (Lcurve as IAbstractF2mCurve).SolveQuadraticEquation(x.Add(curve.a));
+    if (L = Nil) then
     begin
       result := false;
       Exit;
     end;
-    w := x.Multiply(lambda).Add(n.AffineYCoord);
-    t := w.Add(Lcurve.a);
-    result := ((t as IAbstractF2mFieldElement).Trace() = 0) or
-      ((t.Add(x) as IAbstractF2mFieldElement).Trace() = 0);
+
+    (*
+      * A solution exists, therefore 0 == Tr(X + A) == Tr(X).
+    *)
+    y := n.AffineYCoord;
+    t := x.Multiply(L).Add(y);
+
+    (*
+      * Either T or (T + X) is the square of a half-point's x coordinate (hx). In either
+      * case, the half-point can be halved again when 0 == Tr(hx + A).
+      *
+      * Note: Tr(hx + A) == Tr(hx) == Tr(hx^2) == Tr(T) == Tr(T + X)
+      *
+      * Check that 0 == Tr(T); then there exists a solution to L^2 + L = hx + A, and so a
+      * second halving is possible and this point is four times some other.
+    *)
+    result := (t as IAbstractF2mFieldElement).Trace() = 0;
     Exit;
   end;
 
@@ -6296,6 +6486,12 @@ begin
 
 end;
 
+function TAbstractF2mPoint.ScaleXNegateY(const scale: IECFieldElement)
+  : IECPoint;
+begin
+  result := ScaleX(scale);
+end;
+
 function TAbstractF2mPoint.ScaleY(const scale: IECFieldElement): IECPoint;
 var
   Lx, L, L2: IECFieldElement;
@@ -6327,6 +6523,12 @@ begin
 
 end;
 
+function TAbstractF2mPoint.ScaleYNegateX(const scale: IECFieldElement)
+  : IECPoint;
+begin
+  result := ScaleY(scale);
+end;
+
 function TAbstractF2mPoint.Subtract(const b: IECPoint): IECPoint;
 begin
   if (b.IsInfinity) then
@@ -6480,4 +6682,41 @@ begin
   result := info;
 end;
 
+{ TSimpleLookupTable }
+
+class function TSimpleLookupTable.Copy(const points
+  : TCryptoLibGenericArray<IECPoint>; off, len: Int32)
+  : TCryptoLibGenericArray<IECPoint>;
+var
+  i: Int32;
+begin
+  System.SetLength(result, len);
+  for i := 0 to System.Pred(len) do
+  begin
+    result[i] := points[off + i];
+  end;
+end;
+
+constructor TSimpleLookupTable.Create(const points
+  : TCryptoLibGenericArray<IECPoint>; off, len: Int32);
+begin
+  inherited Create();
+  FPoints := Copy(points, off, len);
+end;
+
+function TSimpleLookupTable.GetSize: Int32;
+begin
+  result := System.Length(FPoints);
+end;
+
+function TSimpleLookupTable.Lookup(index: Int32): IECPoint;
+begin
+  raise EInvalidOperationCryptoLibException.CreateRes(@SUnsupportedOperation);
+end;
+
+function TSimpleLookupTable.LookupVar(index: Int32): IECPoint;
+begin
+  result := FPoints[index];
+end;
+
 end.

+ 1534 - 0
CryptoLib/src/Math/EC/ClpECCompUtilities.pas

@@ -0,0 +1,1534 @@
+{ *********************************************************************************** }
+{ *                              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 ClpECCompUtilities;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  Math,
+  ClpBits,
+  ClpIECC,
+  ClpIPreCompInfo,
+  ClpIWNafPreCompInfo,
+  ClpWNafPreCompInfo,
+  ClpEndoPreCompInfo,
+  ClpIFixedPointPreCompInfo,
+  ClpIPreCompCallBack,
+  ClpBigInteger,
+  ClpIEndoPreCompInfo,
+  ClpIScalarSplitParameters,
+  ClpFixedPointPreCompInfo,
+  ClpCryptoLibTypes,
+  ClpECCurveConstants;
+
+resourcestring
+  SInvalidRange = 'Must be in the Range [2, 16], "width"';
+  SInvalidRange2 = 'Must be in the Range [2, 8], "width"';
+
+type
+  TWNafUtilities = class abstract(TObject)
+
+  strict private
+  const
+    DEFAULT_WINDOW_SIZE_CUTOFFS: array [0 .. 5] of Int32 = (13, 41, 121, 337,
+      897, 2305);
+
+    MAX_WIDTH = Int32(16);
+
+  class var
+    FEMPTY_BYTES: TCryptoLibByteArray;
+    FEMPTY_INTS: TCryptoLibInt32Array;
+
+  type
+    IMapPointCallback = interface(IPreCompCallback)
+      ['{730BF27F-D5C3-4DF4-AC77-B8653C457C10}']
+
+    end;
+
+  type
+    TMapPointCallback = class(TInterfacedObject, IPreCompCallback,
+      IMapPointCallback)
+
+    strict private
+    var
+      Fm_wnafPreCompP: IWNafPreCompInfo;
+      Fm_includeNegated: Boolean;
+      Fm_pointMap: IECPointMap;
+
+    public
+      constructor Create(const wnafPreCompP: IWNafPreCompInfo;
+        includeNegated: Boolean; const pointMap: IECPointMap);
+
+      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
+
+    end;
+
+  type
+    IWNafCallback = interface(IPreCompCallback)
+      ['{A439A606-7899-4720-937E-C2F3D94D4811}']
+
+    end;
+
+  type
+    TWNafCallback = class(TInterfacedObject, IPreCompCallback, IWNafCallback)
+
+    strict private
+
+    var
+      Fm_p: IECPoint;
+      FminWidth: Int32;
+      Fm_includeNegated: Boolean;
+
+      class function CheckExisting(const existingWNaf: IWNafPreCompInfo;
+        width, reqPreCompLen: Int32; includeNegated: Boolean): Boolean;
+        static; inline;
+
+      class function CheckTable(const table: TCryptoLibGenericArray<IECPoint>;
+        reqLen: Int32): Boolean; static; inline;
+
+    public
+      constructor Create(const p: IECPoint; minWidth: Int32;
+        includeNegated: Boolean);
+
+      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
+
+    end;
+
+  type
+    IPointMapCallback = interface(IPreCompCallback)
+      ['{00A66D4E-7D61-4A47-AE36-E8D89DEE8D9F}']
+
+    end;
+
+  type
+    TPointMapCallback = class(TInterfacedObject, IPreCompCallback,
+      IPointMapCallback)
+
+    strict private
+
+    var
+      Fm_p: IECPoint;
+      FpointMap: IECPointMap;
+      FfromWNaf: IWNafPreCompInfo;
+      FIncludeNegated: Boolean;
+
+      class function CheckExisting(const existingWNaf: IWNafPreCompInfo;
+        width, reqPreCompLen: Int32; includeNegated: Boolean): Boolean;
+        static; inline;
+
+      class function CheckTable(const table: TCryptoLibGenericArray<IECPoint>;
+        reqLen: Int32): Boolean; static; inline;
+
+    public
+      constructor Create(const p: IECPoint; const pointMap: IECPointMap;
+        const fromWNaf: IWNafPreCompInfo; includeNegated: Boolean);
+
+      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
+
+    end;
+
+  type
+    IBasePointCallback = interface(IPreCompCallback)
+      ['{5A81CB00-3CB4-474D-A2A7-E949F7E71AEC}']
+
+    end;
+
+  type
+    TBasePointCallback = class(TInterfacedObject, IPreCompCallback,
+      IBasePointCallback)
+
+    strict private
+    var
+      FConfWidth: Int32;
+
+    public
+      constructor Create(ConfWidth: Int32);
+
+      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
+
+    end;
+
+  class function Trim(const a: TCryptoLibByteArray; length: Int32)
+    : TCryptoLibByteArray; overload; static; inline;
+
+  class function Trim(const a: TCryptoLibInt32Array; length: Int32)
+    : TCryptoLibInt32Array; overload; static; inline;
+
+  class function ResizeTable(const a: TCryptoLibGenericArray<IECPoint>;
+    length: Int32): TCryptoLibGenericArray<IECPoint>; static; inline;
+
+  class procedure Boot(); static;
+  class constructor CreateWNafUtilities();
+
+  public
+
+    const
+    PRECOMP_NAME: String = 'bc_wnaf';
+
+    class function GenerateCompactNaf(const k: TBigInteger)
+      : TCryptoLibInt32Array; static;
+    class function GenerateCompactWindowNaf(width: Int32; const k: TBigInteger)
+      : TCryptoLibInt32Array; static;
+
+    class function GenerateJsf(const g, h: TBigInteger)
+      : TCryptoLibByteArray; static;
+    class function GenerateNaf(const k: TBigInteger)
+      : TCryptoLibByteArray; static;
+    // /**
+    // * Computes the Window NAF (non-adjacent Form) of an integer.
+    // * @param width The width <code>w</code> of the Window NAF. The width is
+    // * defined as the minimal number <code>w</code>, such that for any
+    // * <code>w</code> consecutive digits in the resulting representation, at
+    // * most one is non-zero.
+    // * @param k The integer of which the Window NAF is computed.
+    // * @return The Window NAF of the given width, such that the following holds:
+    // * <code>k = &amp;sum;<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup>
+    // * </code>, where the <code>k<sub>i</sub></code> denote the elements of the
+    // * returned <code>byte[]</code>.
+    // */
+    class function GenerateWindowNaf(width: Int32; const k: TBigInteger)
+      : TCryptoLibByteArray; static;
+
+    class function GetNafWeight(const k: TBigInteger): Int32; static; inline;
+
+    class function GetWNafPreCompInfo(const p: IECPoint): IWNafPreCompInfo;
+      overload; static; inline;
+
+    class function GetWNafPreCompInfo(const preCompInfo: IPreCompInfo)
+      : IWNafPreCompInfo; overload; static; inline;
+
+    /// <summary>
+    /// Determine window width to use for a scalar multiplication of the
+    /// given size.
+    /// </summary>
+    /// <param name="bits">
+    /// the bit-length of the scalar to multiply by
+    /// </param>
+    /// <returns>
+    /// the window size to use
+    /// </returns>
+    class function GetWindowSize(bits: Int32): Int32; overload; static; inline;
+
+    /// <summary>
+    /// Determine window width to use for a scalar multiplication of the
+    /// given size.
+    /// </summary>
+    /// <param name="bits">
+    /// the bit-length of the scalar to multiply by
+    /// </param>
+    /// <param name="maxWidth">
+    /// the maximum window width to return
+    /// </param>
+    /// <returns>
+    /// the window size to use
+    /// </returns>
+    class function GetWindowSize(bits, maxWidth: Int32): Int32; overload;
+      static; inline;
+
+    /// <summary>
+    /// Determine window width to use for a scalar multiplication of the
+    /// given size.
+    /// </summary>
+    /// <param name="bits">
+    /// the bit-length of the scalar to multiply by
+    /// </param>
+    /// <param name="windowSizeCutoffs">
+    /// a monotonically increasing list of bit sizes at which to increment
+    /// the window width
+    /// </param>
+    /// <returns>
+    /// the window size to use
+    /// </returns>
+    class function GetWindowSize(bits: Int32;
+      const windowSizeCutoffs: array of Int32): Int32; overload; static;
+
+    /// <summary>
+    /// Determine window width to use for a scalar multiplication of the
+    /// given size.
+    /// </summary>
+    /// <param name="bits">
+    /// the bit-length of the scalar to multiply by
+    /// </param>
+    /// <param name="windowSizeCutoffs">
+    /// a monotonically increasing list of bit sizes at which to increment
+    /// the window width
+    /// </param>
+    /// /// <param name="maxWidth">
+    /// the maximum window width to return
+    /// </param>
+    /// <returns>
+    /// the window size to use
+    /// </returns>
+    class function GetWindowSize(bits: Int32;
+      const windowSizeCutoffs: array of Int32; maxWidth: Int32): Int32;
+      overload; static;
+
+    class function Precompute(const p: IECPoint; minWidth: Int32;
+      includeNegated: Boolean): IWNafPreCompInfo; static;
+
+    class procedure ConfigureBasepoint(const p: IECPoint); static;
+
+    class function PrecomputeWithPointMap(const p: IECPoint;
+      const pointMap: IECPointMap; const fromWNaf: IWNafPreCompInfo;
+      includeNegated: Boolean): IWNafPreCompInfo;
+
+  end;
+
+type
+  TEndoUtilities = class abstract(TObject)
+
+  strict private
+  type
+    IEndoCallback = interface(IPreCompCallback)
+      ['{80C0B850-A97A-4603-A42F-A476ABAF2026}']
+
+    end;
+
+  type
+    TEndoCallback = class(TInterfacedObject, IPreCompCallback, IEndoCallback)
+
+    strict private
+    var
+      Fendomorphism: IECEndomorphism;
+      Fp: IECPoint;
+
+      class function CheckExisting(const existingEndo: IEndoPreCompInfo;
+        const endomorphism: IECEndomorphism): Boolean; static; inline;
+
+    public
+      constructor Create(const endomorphism: IECEndomorphism;
+        const p: IECPoint);
+
+      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
+
+    end;
+
+  class function CalculateB(const k, g: TBigInteger; t: Int32)
+    : TBigInteger; static;
+
+  public
+
+    const
+    PRECOMP_NAME: String = 'bc_endo';
+
+  public
+    class function MapPoint(const endomorphism: IECEndomorphism;
+      const p: IECPoint): IECPoint; static;
+
+    class function DecomposeScalar(const p: IScalarSplitParameters;
+      const k: TBigInteger): TCryptoLibGenericArray<TBigInteger>; static;
+
+  end;
+
+type
+  TFixedPointUtilities = class sealed(TObject)
+  strict private
+
+  type
+    IFixedPointCallback = interface(IPreCompCallback)
+      ['{E6DFE8D3-A890-4568-AA4A-3D8BC6AF16E9}']
+
+    end;
+
+  type
+    TFixedPointCallback = class(TInterfacedObject, IPreCompCallback,
+      IFixedPointCallback)
+
+    strict private
+    var
+      Fm_p: IECPoint;
+
+      class function CheckExisting(const existingFP: IFixedPointPreCompInfo;
+        n: Int32): Boolean; static; inline;
+
+      class function CheckTable(const table: IECLookupTable; n: Int32): Boolean;
+        static; inline;
+
+    public
+      constructor Create(const p: IECPoint);
+
+      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
+
+    end;
+
+  const
+    PRECOMP_NAME: String = 'bc_fixed_point';
+
+  public
+
+    class function GetFixedPointPreCompInfo(const preCompInfo: IPreCompInfo)
+      : IFixedPointPreCompInfo; static; inline;
+
+    class function GetCombSize(const c: IECCurve): Int32; static; inline;
+
+    class function Precompute(const p: IECPoint)
+      : IFixedPointPreCompInfo; static;
+  end;
+
+implementation
+
+{ TWNafUtilities }
+
+uses
+  ClpECAlgorithms; // included here to avoid circular dependency :)
+
+class function TWNafUtilities.ResizeTable
+  (const a: TCryptoLibGenericArray<IECPoint>; length: Int32)
+  : TCryptoLibGenericArray<IECPoint>;
+begin
+  result := System.Copy(a);
+  System.SetLength(result, length);
+end;
+
+class function TWNafUtilities.Trim(const a: TCryptoLibInt32Array; length: Int32)
+  : TCryptoLibInt32Array;
+begin
+  result := System.Copy(a, 0, length);
+end;
+
+class function TWNafUtilities.Trim(const a: TCryptoLibByteArray; length: Int32)
+  : TCryptoLibByteArray;
+begin
+  result := System.Copy(a, 0, length);
+end;
+
+class procedure TWNafUtilities.Boot;
+begin
+  FEMPTY_BYTES := Nil;
+  FEMPTY_INTS := Nil;
+end;
+
+class constructor TWNafUtilities.CreateWNafUtilities;
+begin
+  TWNafUtilities.Boot;
+end;
+
+class function TWNafUtilities.GetWindowSize(bits: Int32;
+  const windowSizeCutoffs: array of Int32; maxWidth: Int32): Int32;
+var
+  w: Int32;
+begin
+  w := 0;
+  while (w < System.length(windowSizeCutoffs)) do
+  begin
+    if (bits < windowSizeCutoffs[w]) then
+    begin
+      break;
+    end;
+    System.Inc(w);
+  end;
+
+  result := Max(2, Min(maxWidth, w + 2));
+end;
+
+class function TWNafUtilities.GetWindowSize(bits: Int32;
+  const windowSizeCutoffs: array of Int32): Int32;
+begin
+  result := GetWindowSize(bits, windowSizeCutoffs, MAX_WIDTH);
+end;
+
+class function TWNafUtilities.GetWindowSize(bits, maxWidth: Int32): Int32;
+begin
+  result := GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, maxWidth);
+end;
+
+class function TWNafUtilities.GetWindowSize(bits: Int32): Int32;
+begin
+  result := GetWindowSize(bits, DEFAULT_WINDOW_SIZE_CUTOFFS, MAX_WIDTH);
+end;
+
+class procedure TWNafUtilities.ConfigureBasepoint(const p: IECPoint);
+var
+  c: IECCurve;
+  n: TBigInteger;
+  bits, ConfWidth: Int32;
+begin
+  c := p.Curve;
+  if (c = Nil) then
+  begin
+    Exit;
+  end;
+
+  n := c.Order;
+  if (not n.IsInitialized) then
+  begin
+    bits := c.FieldSize + 1;
+  end
+  else
+  begin
+    bits := n.BitLength;
+  end;
+
+  ConfWidth := Min(MAX_WIDTH, GetWindowSize(bits) + 3);
+
+  c.Precompute(p, PRECOMP_NAME, TBasePointCallback.Create(ConfWidth)
+    as IBasePointCallback);
+end;
+
+class function TWNafUtilities.GenerateCompactNaf(const k: TBigInteger)
+  : TCryptoLibInt32Array;
+var
+  _3k, diff: TBigInteger;
+  bits, highBit, &length, zeroes, i, digit: Int32;
+  naf: TCryptoLibInt32Array;
+begin
+  if ((TBits.Asr32(k.BitLength, 16)) <> 0) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidBitLength);
+  end;
+  if (k.SignValue = 0) then
+  begin
+    result := FEMPTY_INTS;
+    Exit;
+  end;
+
+  _3k := k.ShiftLeft(1).Add(k);
+
+  bits := _3k.BitLength;
+  System.SetLength(naf, TBits.Asr32(bits, 1));
+
+  diff := _3k.&Xor(k);
+
+  highBit := bits - 1;
+  &length := 0;
+  zeroes := 0;
+
+  i := 1;
+
+  while (i < highBit) do
+  begin
+    if (not diff.TestBit(i)) then
+    begin
+      System.Inc(zeroes);
+      System.Inc(i);
+      continue;
+    end;
+
+    if k.TestBit(i) then
+    begin
+      digit := -1;
+    end
+    else
+    begin
+      digit := 1;
+    end;
+
+    naf[length] := (digit shl 16) or zeroes;
+    System.Inc(length);
+    zeroes := 1;
+
+    System.Inc(i, 2);
+
+  end;
+
+  naf[length] := (1 shl 16) or zeroes;
+  System.Inc(length);
+
+  if (System.length(naf) > length) then
+  begin
+    naf := Trim(naf, length);
+  end;
+
+  result := naf;
+end;
+
+class function TWNafUtilities.GenerateCompactWindowNaf(width: Int32;
+  const k: TBigInteger): TCryptoLibInt32Array;
+var
+  wnaf: TCryptoLibInt32Array;
+  pow2, mask, sign, &length, &pos, digit, zeroes: Int32;
+  carry: Boolean;
+  LK: TBigInteger;
+begin
+  LK := k;
+  if (width = 2) then
+  begin
+    result := GenerateCompactNaf(LK);
+    Exit;
+  end;
+
+  if ((width < 2) or (width > 16)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidRange);
+  end;
+  if ((TBits.Asr32(LK.BitLength, 16)) <> 0) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidBitLength);
+  end;
+  if (LK.SignValue = 0) then
+  begin
+    result := FEMPTY_INTS;
+    Exit;
+  end;
+
+  System.SetLength(wnaf, (LK.BitLength div width) + 1);
+
+  // 2^width and a mask and sign bit set accordingly
+  pow2 := 1 shl width;
+  mask := pow2 - 1;
+  sign := TBits.Asr32(pow2, 1);
+
+  carry := false;
+  length := 0;
+  pos := 0;
+
+  while (pos <= LK.BitLength) do
+  begin
+    if (LK.TestBit(pos) = carry) then
+    begin
+      System.Inc(pos);
+      continue;
+    end;
+
+    LK := LK.ShiftRight(pos);
+
+    digit := LK.Int32Value and mask;
+    if (carry) then
+    begin
+      System.Inc(digit);
+    end;
+
+    carry := (digit and sign) <> 0;
+    if (carry) then
+    begin
+      digit := digit - pow2;
+    end;
+
+    if length > 0 then
+    begin
+      zeroes := pos - 1;
+    end
+    else
+    begin
+      zeroes := pos;
+    end;
+
+    wnaf[length] := (digit shl 16) or zeroes;
+    System.Inc(length);
+    pos := width;
+  end;
+
+  // Reduce the WNAF array to its actual length
+  if (System.length(wnaf) > length) then
+  begin
+    wnaf := Trim(wnaf, length);
+  end;
+
+  result := wnaf;
+end;
+
+class function TWNafUtilities.GenerateJsf(const g, h: TBigInteger)
+  : TCryptoLibByteArray;
+var
+  digits, j, d0, d1, Offset, n0, n1, u0, u1: Int32;
+  jsf: TCryptoLibByteArray;
+  k0, k1: TBigInteger;
+begin
+  digits := Max(g.BitLength, h.BitLength) + 1;
+
+  System.SetLength(jsf, digits);
+
+  k0 := g;
+  k1 := h;
+  j := 0;
+  d0 := 0;
+  d1 := 0;
+
+  Offset := 0;
+
+  while (((d0 or d1) <> 0) or (k0.BitLength > Offset) or
+    (k1.BitLength > Offset)) do
+  begin
+    n0 := (Int32(UInt32(k0.Int32Value) shr Offset) + d0) and 7;
+    n1 := (Int32(UInt32(k1.Int32Value) shr Offset) + d1) and 7;
+
+    u0 := n0 and 1;
+    if (u0 <> 0) then
+    begin
+      u0 := u0 - (n0 and 2);
+      if (((n0 + u0) = 4) and ((n1 and 3) = 2)) then
+      begin
+        u0 := -u0;
+      end;
+    end;
+
+    u1 := n1 and 1;
+    if (u1 <> 0) then
+    begin
+      u1 := u1 - (n1 and 2);
+      if (((n1 + u1) = 4) and ((n0 and 3) = 2)) then
+      begin
+        u1 := -u1;
+      end;
+    end;
+
+    if ((d0 shl 1) = (1 + u0)) then
+    begin
+      d0 := d0 xor 1;
+    end;
+    if ((d1 shl 1) = (1 + u1)) then
+    begin
+      d1 := d1 xor 1;
+    end;
+
+    System.Inc(Offset);
+    if (Offset = 30) then
+    begin
+      Offset := 0;
+      k0 := k0.ShiftRight(30);
+      k1 := k1.ShiftRight(30);
+    end;
+
+    jsf[j] := Byte((u0 shl 4) or (u1 and $F));
+    System.Inc(j);
+  end;
+
+  // Reduce the JSF array to its actual length
+  if (System.length(jsf) > j) then
+  begin
+    jsf := Trim(jsf, j);
+  end;
+
+  result := jsf;
+end;
+
+class function TWNafUtilities.GenerateNaf(const k: TBigInteger)
+  : TCryptoLibByteArray;
+var
+  _3k, diff: TBigInteger;
+  digits, i: Int32;
+  naf: TCryptoLibByteArray;
+begin
+  if (k.SignValue = 0) then
+  begin
+    result := FEMPTY_BYTES;
+    Exit;
+  end;
+
+  _3k := k.ShiftLeft(1).Add(k);
+
+  digits := _3k.BitLength - 1;
+  System.SetLength(naf, digits);
+
+  diff := _3k.&Xor(k);
+
+  i := 1;
+
+  while i < digits do
+  begin
+    if (diff.TestBit(i)) then
+    begin
+      if k.TestBit(i) then
+      begin
+        naf[i - 1] := Byte(-1);
+      end
+      else
+      begin
+        naf[i - 1] := Byte(1);
+      end;
+
+      System.Inc(i);
+    end;
+    System.Inc(i);
+  end;
+
+  naf[digits - 1] := 1;
+
+  result := naf;
+end;
+
+class function TWNafUtilities.GenerateWindowNaf(width: Int32;
+  const k: TBigInteger): TCryptoLibByteArray;
+var
+  wnaf: TCryptoLibByteArray;
+  pow2, mask, sign, &length, &pos, digit: Int32;
+  carry: Boolean;
+  LK: TBigInteger;
+begin
+  LK := k;
+  if (width = 2) then
+  begin
+    result := GenerateNaf(LK);
+    Exit;
+  end;
+
+  if ((width < 2) or (width > 8)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidRange2);
+  end;
+  if (LK.SignValue = 0) then
+  begin
+    result := FEMPTY_BYTES;
+    Exit;
+  end;
+
+  System.SetLength(wnaf, LK.BitLength + 1);
+
+  // 2^width and a mask and sign bit set accordingly
+  pow2 := 1 shl width;
+  mask := pow2 - 1;
+  sign := TBits.Asr32(pow2, 1);
+
+  carry := false;
+  length := 0;
+  pos := 0;
+
+  while (pos <= LK.BitLength) do
+  begin
+    if (LK.TestBit(pos) = carry) then
+    begin
+      System.Inc(pos);
+      continue;
+    end;
+
+    LK := LK.ShiftRight(pos);
+
+    digit := LK.Int32Value and mask;
+    if (carry) then
+    begin
+      System.Inc(digit);
+    end;
+
+    carry := (digit and sign) <> 0;
+    if (carry) then
+    begin
+      digit := digit - pow2;
+    end;
+
+    if length > 0 then
+    begin
+      length := length + (pos - 1);
+    end
+    else
+    begin
+      length := length + (pos);
+    end;
+
+    wnaf[length] := Byte(digit);
+    System.Inc(length);
+    pos := width;
+  end;
+
+  // Reduce the WNAF array to its actual length
+  if (System.length(wnaf) > length) then
+  begin
+    wnaf := Trim(wnaf, length);
+  end;
+
+  result := wnaf;
+end;
+
+class function TWNafUtilities.GetNafWeight(const k: TBigInteger): Int32;
+var
+  _3k, diff: TBigInteger;
+begin
+  if (k.SignValue = 0) then
+  begin
+    result := 0;
+    Exit;
+  end;
+
+  _3k := k.ShiftLeft(1).Add(k);
+  diff := _3k.&Xor(k);
+
+  result := diff.BitCount;
+end;
+
+class function TWNafUtilities.GetWNafPreCompInfo(const preCompInfo
+  : IPreCompInfo): IWNafPreCompInfo;
+begin
+  result := preCompInfo as IWNafPreCompInfo;
+end;
+
+class function TWNafUtilities.GetWNafPreCompInfo(const p: IECPoint)
+  : IWNafPreCompInfo;
+var
+  preCompInfo: IPreCompInfo;
+begin
+  preCompInfo := p.Curve.GetPreCompInfo(p, PRECOMP_NAME);
+  result := GetWNafPreCompInfo(preCompInfo);
+end;
+
+class function TWNafUtilities.Precompute(const p: IECPoint; minWidth: Int32;
+  includeNegated: Boolean): IWNafPreCompInfo;
+begin
+  result := p.Curve.Precompute(p, PRECOMP_NAME,
+    TWNafCallback.Create(p, minWidth, includeNegated) as IWNafCallback)
+    as IWNafPreCompInfo;
+end;
+
+class function TWNafUtilities.PrecomputeWithPointMap(const p: IECPoint;
+  const pointMap: IECPointMap; const fromWNaf: IWNafPreCompInfo;
+  includeNegated: Boolean): IWNafPreCompInfo;
+var
+  c: IECCurve;
+begin
+  c := p.Curve;
+  result := c.Precompute(p, PRECOMP_NAME, TPointMapCallback.Create(p, pointMap,
+    fromWNaf, includeNegated) as IPointMapCallback) as IWNafPreCompInfo;
+end;
+
+{ TWNafUtilities.TMapPointCallback }
+
+constructor TWNafUtilities.TMapPointCallback.Create(const wnafPreCompP
+  : IWNafPreCompInfo; includeNegated: Boolean; const pointMap: IECPointMap);
+begin
+  Inherited Create();
+  Fm_wnafPreCompP := wnafPreCompP;
+  Fm_includeNegated := includeNegated;
+  Fm_pointMap := pointMap;
+end;
+
+function TWNafUtilities.TMapPointCallback.Precompute(const existing
+  : IPreCompInfo): IPreCompInfo;
+var
+  tempResult: IWNafPreCompInfo;
+  twiceP, twiceQ: IECPoint;
+  preCompP, preCompQ, preCompNegQ: TCryptoLibGenericArray<IECPoint>;
+  i: Int32;
+begin
+  tempResult := TWNafPreCompInfo.Create();
+
+  tempResult.ConfWidth := Fm_wnafPreCompP.ConfWidth;
+
+  twiceP := Fm_wnafPreCompP.Twice;
+  if (twiceP <> Nil) then
+  begin
+    twiceQ := Fm_pointMap.Map(twiceP);
+    tempResult.Twice := twiceQ;
+  end;
+
+  preCompP := Fm_wnafPreCompP.PreComp;
+
+  System.SetLength(preCompQ, System.length(preCompP));
+  for i := 0 to System.Pred(System.length(preCompP)) do
+  begin
+    preCompQ[i] := Fm_pointMap.Map(preCompP[i]);
+  end;
+
+  tempResult.PreComp := preCompQ;
+  tempResult.width := Fm_wnafPreCompP.width;
+
+  if (Fm_includeNegated) then
+  begin
+
+    System.SetLength(preCompNegQ, System.length(preCompQ));
+
+    for i := 0 to System.Pred(System.length(preCompNegQ)) do
+    begin
+      preCompNegQ[i] := preCompQ[i].Negate();
+    end;
+
+    tempResult.PreCompNeg := preCompNegQ;
+  end;
+
+  result := tempResult;
+end;
+
+{ TWNafUtilities.TWNafCallback }
+
+class function TWNafUtilities.TWNafCallback.CheckTable
+  (const table: TCryptoLibGenericArray<IECPoint>; reqLen: Int32): Boolean;
+begin
+  result := (table <> Nil) and (System.length(table) >= reqLen);
+end;
+
+class function TWNafUtilities.TWNafCallback.CheckExisting(const existingWNaf
+  : IWNafPreCompInfo; width, reqPreCompLen: Int32;
+  includeNegated: Boolean): Boolean;
+begin
+  result := (existingWNaf <> Nil) and
+    (existingWNaf.width >= Max(existingWNaf.ConfWidth, width))
+
+    and CheckTable(existingWNaf.PreComp, reqPreCompLen) and
+    ((not includeNegated) or CheckTable(existingWNaf.PreCompNeg,
+    reqPreCompLen));
+end;
+
+constructor TWNafUtilities.TWNafCallback.Create(const p: IECPoint;
+  minWidth: Int32; includeNegated: Boolean);
+begin
+  Inherited Create();
+  Fm_p := p;
+  FminWidth := minWidth;
+  Fm_includeNegated := includeNegated;
+end;
+
+function TWNafUtilities.TWNafCallback.Precompute(const existing: IPreCompInfo)
+  : IPreCompInfo;
+var
+  twiceP, isoTwiceP, last: IECPoint;
+  c: IECCurve;
+  PreComp, PreCompNeg, EMPTY_POINTS: TCryptoLibGenericArray<IECPoint>;
+  tempRes, existingWNaf: IWNafPreCompInfo;
+  reqPreCompLen, iniPreCompLen, curPreCompLen, pos, width, PromotionCountdown,
+    ConfWidth: Int32;
+  iso, iso2, iso3: IECFieldElement;
+begin
+  c := Fm_p.Curve;
+  EMPTY_POINTS := Nil;
+  existingWNaf := existing as IWNafPreCompInfo;
+
+  width := Max(2, Min(MAX_WIDTH, FminWidth));
+  reqPreCompLen := 1 shl (width - 2);
+
+  if (CheckExisting(existingWNaf, width, reqPreCompLen, Fm_includeNegated)) then
+  begin
+    existingWNaf.DecrementPromotionCountdown;
+    result := existingWNaf;
+    Exit;
+  end;
+
+  tempRes := TWNafPreCompInfo.Create();
+
+  if (existingWNaf <> Nil) then
+  begin
+
+    PromotionCountdown := existingWNaf.DecrementPromotionCountdown;
+    tempRes.PromotionCountdown := PromotionCountdown;
+
+    ConfWidth := existingWNaf.ConfWidth;
+    tempRes.ConfWidth := ConfWidth;
+
+    PreComp := existingWNaf.PreComp;
+    PreCompNeg := existingWNaf.PreCompNeg;
+    twiceP := existingWNaf.Twice;
+  end;
+
+  width := Min(MAX_WIDTH, Max(tempRes.ConfWidth, width));
+  reqPreCompLen := 1 shl (width - 2);
+
+  iniPreCompLen := 0;
+  if (PreComp = Nil) then
+  begin
+    PreComp := EMPTY_POINTS;
+  end
+  else
+  begin
+    iniPreCompLen := System.length(PreComp);
+  end;
+
+  if (iniPreCompLen < reqPreCompLen) then
+  begin
+    PreComp := TWNafUtilities.ResizeTable(PreComp, reqPreCompLen);
+
+    if (reqPreCompLen = 1) then
+    begin
+      PreComp[0] := Fm_p.Normalize();
+    end
+    else
+    begin
+      curPreCompLen := iniPreCompLen;
+      if (curPreCompLen = 0) then
+      begin
+        PreComp[0] := Fm_p;
+        curPreCompLen := 1;
+      end;
+
+      if (reqPreCompLen = 2) then
+      begin
+        PreComp[1] := Fm_p.threeTimes();
+      end
+      else
+      begin
+        isoTwiceP := twiceP;
+        last := PreComp[curPreCompLen - 1];
+        if (isoTwiceP = Nil) then
+        begin
+          isoTwiceP := PreComp[0].Twice();
+          twiceP := isoTwiceP;
+          //
+          // /*
+          // * For Fp curves with Jacobian projective coordinates, use a (quasi-)isomorphism
+          // * where 'twiceP' is "affine", so that the subsequent additions are cheaper. This
+          // * also requires scaling the initial point's X, Y coordinates, and reversing the
+          // * isomorphism as part of the subsequent normalization.
+          // *
+          // *  NOTE: The correctness of this optimization depends on:
+          // *      1) additions do not use the curve's A, B coefficients.
+          // *      2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...
+          // */
+          if ((not(twiceP.IsInfinity)) and (TECAlgorithms.IsFpCurve(c)) and
+            (c.FieldSize >= 64)) then
+          begin
+            case (c.CoordinateSystem) of
+              TECCurveConstants.COORD_JACOBIAN,
+                TECCurveConstants.COORD_JACOBIAN_CHUDNOVSKY,
+                TECCurveConstants.COORD_JACOBIAN_MODIFIED:
+
+                begin
+                  iso := twiceP.GetZCoord(0);
+                  isoTwiceP := c.CreatePoint(twiceP.XCoord.ToBigInteger,
+                    twiceP.YCoord.ToBigInteger());
+
+                  iso2 := iso.square();
+                  iso3 := iso2.Multiply(iso);
+                  last := last.scaleX(iso2).scaleY(iso3);
+
+                  if (iniPreCompLen = 0) then
+                  begin
+                    PreComp[0] := last;
+                  end;
+                end;
+
+            end;
+
+          end;
+        end;
+
+        while (curPreCompLen < reqPreCompLen) do
+        begin
+          // /*
+          // * Compute the new ECPoints for the precomputation array. The values 1, 3,
+          // * 5, ..., 2^(width-1)-1 times p are computed
+          // */
+          last := last.Add(isoTwiceP);
+          PreComp[curPreCompLen] := last;
+          System.Inc(curPreCompLen);
+        end;
+      end;
+      //
+      // /*
+      // * Having oft-used operands in affine form makes operations faster.
+      // */
+      c.NormalizeAll(PreComp, iniPreCompLen,
+        reqPreCompLen - iniPreCompLen, iso);
+    end;
+  end;
+
+  if (Fm_includeNegated) then
+  begin
+
+    if (PreCompNeg = Nil) then
+    begin
+      pos := 0;
+      System.SetLength(PreCompNeg, reqPreCompLen);
+
+    end
+    else
+    begin
+      pos := System.length(PreCompNeg);
+      if (pos < reqPreCompLen) then
+      begin
+        PreCompNeg := TWNafUtilities.ResizeTable(PreCompNeg, reqPreCompLen);
+      end;
+    end;
+
+    while (pos < reqPreCompLen) do
+    begin
+      PreCompNeg[pos] := PreComp[pos].Negate();
+      System.Inc(pos);
+    end;
+  end;
+
+  tempRes.PreComp := PreComp;
+  tempRes.PreCompNeg := PreCompNeg;
+  tempRes.Twice := twiceP;
+  tempRes.width := width;
+
+  result := tempRes;
+end;
+
+{ TWNafUtilities.TBasePointCallback }
+
+constructor TWNafUtilities.TBasePointCallback.Create(ConfWidth: Int32);
+begin
+  Inherited Create();
+  FConfWidth := ConfWidth;
+end;
+
+function TWNafUtilities.TBasePointCallback.Precompute(const existing
+  : IPreCompInfo): IPreCompInfo;
+var
+  existingWNaf, tempResult: IWNafPreCompInfo;
+begin
+
+  if Supports(existing, IWNafPreCompInfo) then
+  begin
+    existingWNaf := existing as IWNafPreCompInfo;
+  end
+  else
+  begin
+    existingWNaf := Nil;
+  end;
+
+  if ((existingWNaf <> Nil) and (existingWNaf.ConfWidth = FConfWidth)) then
+  begin
+    existingWNaf.PromotionCountdown := 0;
+    result := existingWNaf;
+    Exit;
+  end;
+
+  tempResult := TWNafPreCompInfo.Create();
+
+  tempResult.PromotionCountdown := 0;
+  tempResult.ConfWidth := FConfWidth;
+
+  if (existingWNaf <> Nil) then
+  begin
+    tempResult.PreComp := existingWNaf.PreComp;
+    tempResult.PreCompNeg := existingWNaf.PreCompNeg;
+    tempResult.Twice := existingWNaf.Twice;
+    tempResult.width := existingWNaf.width;
+  end;
+  result := tempResult;
+end;
+
+{ TWNafUtilities.TPointMapCallback }
+
+class function TWNafUtilities.TPointMapCallback.CheckTable
+  (const table: TCryptoLibGenericArray<IECPoint>; reqLen: Int32): Boolean;
+begin
+  result := ((table <> Nil) and (System.length(table) >= reqLen));
+end;
+
+class function TWNafUtilities.TPointMapCallback.CheckExisting(const existingWNaf
+  : IWNafPreCompInfo; width, reqPreCompLen: Int32;
+  includeNegated: Boolean): Boolean;
+begin
+  result := ((existingWNaf <> Nil) and (existingWNaf.width >= width) and
+    (CheckTable(existingWNaf.PreComp, reqPreCompLen)) and
+    ((not includeNegated) or (CheckTable(existingWNaf.PreCompNeg,
+    reqPreCompLen))));
+end;
+
+constructor TWNafUtilities.TPointMapCallback.Create(const p: IECPoint;
+  const pointMap: IECPointMap; const fromWNaf: IWNafPreCompInfo;
+  includeNegated: Boolean);
+begin
+  Inherited Create();
+  Fm_p := p;
+  FpointMap := pointMap;
+  FfromWNaf := fromWNaf;
+  FIncludeNegated := includeNegated;
+end;
+
+function TWNafUtilities.TPointMapCallback.Precompute(const existing
+  : IPreCompInfo): IPreCompInfo;
+var
+  existingWNaf: IWNafPreCompInfo;
+  width, reqPreCompLen, i: Int32;
+  tempResult: IWNafPreCompInfo;
+  twiceFrom, Ltwice: IECPoint;
+  LpreCompFrom, LpreComp, LpreCompNeg: TCryptoLibGenericArray<IECPoint>;
+begin
+  if Supports(existing, IWNafPreCompInfo) then
+  begin
+    existingWNaf := existing as IWNafPreCompInfo;
+  end
+  else
+  begin
+    existingWNaf := Nil;
+  end;
+  width := FfromWNaf.width;
+  reqPreCompLen := System.length(FfromWNaf.PreComp);
+
+  if (CheckExisting(existingWNaf, width, reqPreCompLen, FIncludeNegated)) then
+  begin
+    existingWNaf.DecrementPromotionCountdown;
+    result := existingWNaf;
+    Exit;
+  end;
+
+  (*
+    * TODO Ideally this method would support incremental calculation, but given the
+    * existing use-cases it would be of little-to-no benefit.
+  *)
+  tempResult := TWNafPreCompInfo.Create();
+
+  tempResult.PromotionCountdown := FfromWNaf.PromotionCountdown;
+
+  twiceFrom := FfromWNaf.Twice;
+  if (twiceFrom <> Nil) then
+  begin
+    Ltwice := FpointMap.Map(twiceFrom);
+    tempResult.Twice := Ltwice;
+  end;
+
+  LpreCompFrom := FfromWNaf.PreComp;
+  System.SetLength(LpreComp, System.length(LpreCompFrom));
+
+  for i := 0 to System.Pred(System.length(LpreCompFrom)) do
+  begin
+    LpreComp[i] := FpointMap.Map(LpreCompFrom[i]);
+  end;
+  tempResult.PreComp := LpreComp;
+  tempResult.width := width;
+
+  if (FIncludeNegated) then
+  begin
+    System.SetLength(LpreCompNeg, System.length(LpreComp));
+
+    for i := 0 to System.Pred(System.length(LpreCompNeg)) do
+    begin
+      LpreCompNeg[i] := LpreComp[i].Negate();
+    end;
+    tempResult.PreCompNeg := LpreCompNeg;
+  end;
+
+  result := tempResult;
+end;
+
+{ TEndoUtilities }
+
+class function TEndoUtilities.CalculateB(const k, g: TBigInteger; t: Int32)
+  : TBigInteger;
+var
+  negative, extra: Boolean;
+  b: TBigInteger;
+begin
+  negative := (g.SignValue < 0);
+  b := k.Multiply(g.Abs());
+  extra := b.TestBit(t - 1);
+  b := b.ShiftRight(t);
+  if (extra) then
+  begin
+    b := b.Add(TBigInteger.One);
+  end;
+
+  if negative then
+  begin
+    result := b.Negate();
+  end
+  else
+  begin
+    result := b;
+  end;
+end;
+
+class function TEndoUtilities.DecomposeScalar(const p: IScalarSplitParameters;
+  const k: TBigInteger): TCryptoLibGenericArray<TBigInteger>;
+var
+  bits: Int32;
+  b1, b2, a, b: TBigInteger;
+begin
+
+  bits := p.bits;
+  b1 := CalculateB(k, p.G1, bits);
+  b2 := CalculateB(k, p.G2, bits);
+
+  a := k.Subtract((b1.Multiply(p.V1A)).Add(b2.Multiply(p.V2A)));
+  b := (b1.Multiply(p.V1B)).Add(b2.Multiply(p.V2B)).Negate();
+
+  result := TCryptoLibGenericArray<TBigInteger>.Create(a, b);
+end;
+
+class function TEndoUtilities.MapPoint(const endomorphism: IECEndomorphism;
+  const p: IECPoint): IECPoint;
+var
+  c: IECCurve;
+  PreComp: IEndoPreCompInfo;
+begin
+  c := p.Curve;
+  PreComp := c.Precompute(p, PRECOMP_NAME, TEndoCallback.Create(endomorphism, p)
+    as IEndoCallback) as IEndoPreCompInfo;
+
+  result := PreComp.MappedPoint;
+end;
+
+{ TEndoUtilities.TEndoCallback }
+
+class function TEndoUtilities.TEndoCallback.CheckExisting(const existingEndo
+  : IEndoPreCompInfo; const endomorphism: IECEndomorphism): Boolean;
+begin
+  result := ((existingEndo <> Nil) and
+    (existingEndo.endomorphism = endomorphism) and
+    (existingEndo.MappedPoint <> Nil));
+end;
+
+constructor TEndoUtilities.TEndoCallback.Create(const endomorphism
+  : IECEndomorphism; const p: IECPoint);
+begin
+  Inherited Create();
+  Fendomorphism := endomorphism;
+  Fp := p;
+end;
+
+function TEndoUtilities.TEndoCallback.Precompute(const existing: IPreCompInfo)
+  : IPreCompInfo;
+var
+  existingEndo: IEndoPreCompInfo;
+  MappedPoint: IECPoint;
+  tempResult: IEndoPreCompInfo;
+begin
+
+  if Supports(existing, IEndoPreCompInfo) then
+  begin
+    existingEndo := existing as IEndoPreCompInfo;
+  end
+  else
+  begin
+    existingEndo := Nil;
+  end;
+
+  if (CheckExisting(existingEndo, Fendomorphism)) then
+  begin
+    result := existingEndo;
+    Exit;
+  end;
+
+  MappedPoint := Fendomorphism.pointMap.Map(Fp);
+
+  tempResult := TEndoPreCompInfo.Create() as IEndoPreCompInfo;
+  tempResult.endomorphism := Fendomorphism;
+  tempResult.MappedPoint := MappedPoint;
+  result := tempResult as IPreCompInfo;
+end;
+
+{ TFixedPointUtilities }
+
+class function TFixedPointUtilities.TFixedPointCallback.CheckTable
+  (const table: IECLookupTable; n: Int32): Boolean;
+begin
+  result := (table <> Nil) and (table.Size >= n);
+end;
+
+class function TFixedPointUtilities.TFixedPointCallback.CheckExisting
+  (const existingFP: IFixedPointPreCompInfo; n: Int32): Boolean;
+begin
+  result := (existingFP <> Nil) and CheckTable(existingFP.LookupTable, n);
+end;
+
+class function TFixedPointUtilities.GetCombSize(const c: IECCurve): Int32;
+var
+  Order: TBigInteger;
+begin
+  Order := c.Order;
+  if (not(Order.IsInitialized)) then
+  begin
+    result := c.FieldSize + 1;
+  end
+  else
+  begin
+    result := Order.BitLength;
+  end;
+end;
+
+class function TFixedPointUtilities.GetFixedPointPreCompInfo(const preCompInfo
+  : IPreCompInfo): IFixedPointPreCompInfo;
+begin
+  result := preCompInfo as IFixedPointPreCompInfo;
+end;
+
+class function TFixedPointUtilities.Precompute(const p: IECPoint)
+  : IFixedPointPreCompInfo;
+var
+  c: IECCurve;
+begin
+  c := p.Curve;
+
+  result := c.Precompute(p, PRECOMP_NAME, TFixedPointCallback.Create(p)
+    as IFixedPointCallback) as IFixedPointPreCompInfo;
+end;
+
+{ TFixedPointUtilities.TFixedPointCallback }
+
+constructor TFixedPointUtilities.TFixedPointCallback.Create(const p: IECPoint);
+begin
+  Inherited Create();
+  Fm_p := p;
+end;
+
+function TFixedPointUtilities.TFixedPointCallback.Precompute(const existing
+  : IPreCompInfo): IPreCompInfo;
+var
+  bit, bits, minWidth, n, d, i, step: Int32;
+  existingFP: IFixedPointPreCompInfo;
+  pow2Table, LookupTable: TCryptoLibGenericArray<IECPoint>;
+  pow2: IECPoint;
+  c: IECCurve;
+  tempResult: IFixedPointPreCompInfo;
+begin
+  if Supports(existing, IFixedPointPreCompInfo) then
+  begin
+    existingFP := existing as IFixedPointPreCompInfo;
+  end
+  else
+  begin
+    existingFP := Nil;
+  end;
+
+  c := Fm_p.Curve;
+  bits := TFixedPointUtilities.GetCombSize(c);
+  if bits > 250 then
+  begin
+    minWidth := 6
+  end
+  else
+  begin
+    minWidth := 5
+  end;
+  n := 1 shl minWidth;
+
+  if (CheckExisting(existingFP, n)) then
+  begin
+    result := existingFP;
+    Exit;
+  end;
+
+  d := (bits + minWidth - 1) div minWidth;
+
+  System.SetLength(pow2Table, minWidth + 1);
+
+  pow2Table[0] := Fm_p;
+  for i := 1 to System.Pred(minWidth) do
+  begin
+    pow2Table[i] := pow2Table[i - 1].TimesPow2(d);
+  end;
+
+  // This will be the 'offset' value
+  pow2Table[minWidth] := pow2Table[0].Subtract(pow2Table[1]);
+
+  c.NormalizeAll(pow2Table);
+
+  System.SetLength(LookupTable, n);
+  LookupTable[0] := pow2Table[0];
+
+  bit := minWidth - 1;
+  while bit >= 0 do
+  begin
+    pow2 := pow2Table[bit];
+
+    step := 1 shl bit;
+
+    i := step;
+
+    while i < n do
+    begin
+      LookupTable[i] := LookupTable[i - step].Add(pow2);
+
+      System.Inc(i, step shl 1);
+    end;
+
+    System.Dec(bit);
+  end;
+
+  c.NormalizeAll(LookupTable);
+
+  tempResult := TFixedPointPreCompInfo.Create();
+  tempResult.LookupTable := c.CreateCacheSafeLookupTable(LookupTable, 0,
+    System.length(LookupTable));
+  tempResult.Offset := pow2Table[minWidth];
+  tempResult.width := minWidth;
+  result := tempResult;
+end;
+
+end.

+ 56 - 0
CryptoLib/src/Math/EC/ClpScaleXNegateYPointMap.pas

@@ -0,0 +1,56 @@
+{ *********************************************************************************** }
+{ *                              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 ClpScaleXNegateYPointMap;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIECC,
+  ClpIScaleXNegateYPointMap;
+
+type
+  TScaleXNegateYPointMap = class(TInterfacedObject, IECPointMap,
+    IScaleXNegateYPointMap)
+
+  strict protected
+  var
+    Fscale: IECFieldElement;
+
+  public
+    constructor Create(const scale: IECFieldElement);
+    function Map(const p: IECPoint): IECPoint; virtual;
+  end;
+
+implementation
+
+{ TScaleXNegateYPointMap }
+
+constructor TScaleXNegateYPointMap.Create(const scale: IECFieldElement);
+begin
+  Inherited Create();
+  Fscale := scale;
+end;
+
+function TScaleXNegateYPointMap.Map(const p: IECPoint): IECPoint;
+begin
+  Result := p.ScaleXNegateY(Fscale);
+end;
+
+end.

+ 56 - 0
CryptoLib/src/Math/EC/ClpScaleYNegateXPointMap.pas

@@ -0,0 +1,56 @@
+{ *********************************************************************************** }
+{ *                              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 ClpScaleYNegateXPointMap;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIECC,
+  ClpIScaleYNegateXPointMap;
+
+type
+  TScaleYNegateXPointMap = class(TInterfacedObject, IECPointMap,
+    IScaleYNegateXPointMap)
+
+  strict protected
+  var
+    Fscale: IECFieldElement;
+
+  public
+    constructor Create(const scale: IECFieldElement);
+    function Map(const p: IECPoint): IECPoint; virtual;
+  end;
+
+implementation
+
+{ TScaleYNegateXPointMap }
+
+constructor TScaleYNegateXPointMap.Create(const scale: IECFieldElement);
+begin
+  Inherited Create();
+  Fscale := scale;
+end;
+
+function TScaleYNegateXPointMap.Map(const p: IECPoint): IECPoint;
+begin
+  Result := p.ScaleYNegateX(Fscale);
+end;
+
+end.

+ 51 - 12
CryptoLib/src/Math/EC/Custom/Djb/ClpCurve25519Custom.pas

@@ -237,8 +237,8 @@ type
   strict private
 
   type
-    TCurve25519LookupTable = class sealed(TInterfacedObject,
-      ICurve25519LookupTable, IECLookupTable)
+    TCurve25519LookupTable = class sealed(TAbstractECLookupTable,
+      ICurve25519LookupTable)
 
     strict private
     var
@@ -246,16 +246,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
     public
 
       constructor Create(const outer: ICurve25519;
         const table: TCryptoLibUInt32Array; size: Int32);
 
-      function Lookup(index: Int32): IECPoint; virtual;
-
-      property size: Int32 read GetSize;
+      function Lookup(index: Int32): IECPoint; override;
+      function LookupVar(index: Int32): IECPoint; override;
 
     end;
 
@@ -1239,13 +1242,13 @@ begin
   Fm_infinity := TCurve25519Point.Create(Self as IECCurve, Nil, Nil);
 
   Fm_a := FromBigInteger(TBigInteger.Create(1,
-    THex.Decode
+    THex.decode
     ('2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144')));
   Fm_b := FromBigInteger(TBigInteger.Create(1,
-    THex.Decode
+    THex.decode
     ('7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864')));
   Fm_order := TBigInteger.Create(1,
-    THex.Decode
+    THex.decode
     ('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED'));
   Fm_cofactor := TBigInteger.ValueOf(8);
   Fm_coord := Curve25519_DEFAULT_COORDS;
@@ -1333,6 +1336,26 @@ begin
   Fm_size := size;
 end;
 
+function TCurve25519.TCurve25519LookupTable.CreatePoint(const x,
+  y: TCryptoLibUInt32Array): IECPoint;
+var
+  XFieldElement, YFieldElement: ICurve25519FieldElement;
+  CURVE25519_AFFINE_ZS: TCryptoLibGenericArray<IECFieldElement>;
+  C_a: TBigInteger;
+begin
+  C_a := TBigInteger.Create(1,
+    THex.decode
+    ('2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144'));
+  CURVE25519_AFFINE_ZS := TCryptoLibGenericArray<IECFieldElement>.Create
+    (TCurve25519FieldElement.Create(TBigInteger.One) as ICurve25519FieldElement,
+    TCurve25519FieldElement.Create(C_a) as ICurve25519FieldElement);
+
+  XFieldElement := TCurve25519FieldElement.Create(x);
+  YFieldElement := TCurve25519FieldElement.Create(y);
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement,
+    CURVE25519_AFFINE_ZS, false);
+end;
+
 function TCurve25519.TCurve25519LookupTable.GetSize: Int32;
 begin
   result := Fm_size;
@@ -1361,9 +1384,25 @@ begin
     pos := pos + (CURVE25519_FE_INTS * 2);
   end;
 
-  result := Fm_outer.CreateRawPoint(TCurve25519FieldElement.Create(x)
-    as ICurve25519FieldElement, TCurve25519FieldElement.Create(y)
-    as ICurve25519FieldElement, false);
+  result := CreatePoint(x, y)
+end;
+
+function TCurve25519.TCurve25519LookupTable.LookupVar(index: Int32): IECPoint;
+var
+  x, y: TCryptoLibUInt32Array;
+  pos, J: Int32;
+begin
+  x := TNat256.Create();
+  y := TNat256.Create();
+  pos := index * CURVE25519_FE_INTS * 2;
+
+  for J := 0 to System.Pred(CURVE25519_FE_INTS) do
+  begin
+    x[J] := Fm_table[pos + J];
+    y[J] := Fm_table[pos + CURVE25519_FE_INTS + J];
+  end;
+
+  result := CreatePoint(x, y)
 end;
 
 end.

+ 44 - 9
CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256K1Custom.pas

@@ -211,8 +211,8 @@ type
   strict private
 
   type
-    TSecP256K1LookupTable = class sealed(TInterfacedObject,
-      ISecP256K1LookupTable, IECLookupTable)
+    TSecP256K1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecP256K1LookupTable)
 
     strict private
     var
@@ -220,16 +220,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
     public
 
       constructor Create(const outer: ISecP256K1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
 
-      function Lookup(index: Int32): IECPoint; virtual;
-
-      property size: Int32 read GetSize;
+      function Lookup(index: Int32): IECPoint; override;
+      function LookupVar(index: Int32): IECPoint; override;
 
     end;
 
@@ -1126,6 +1129,21 @@ begin
   Fm_size := size;
 end;
 
+function TSecP256K1Curve.TSecP256K1LookupTable.CreatePoint(const x,
+  y: TCryptoLibUInt32Array): IECPoint;
+var
+  XFieldElement, YFieldElement: ISecP256K1FieldElement;
+  SECP256K1_AFFINE_ZS: TCryptoLibGenericArray<IECFieldElement>;
+begin
+  SECP256K1_AFFINE_ZS := TCryptoLibGenericArray<IECFieldElement>.Create
+    (TSecP256K1FieldElement.Create(TBigInteger.One) as ISecP256K1FieldElement);
+
+  XFieldElement := TSecP256K1FieldElement.Create(x);
+  YFieldElement := TSecP256K1FieldElement.Create(y);
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement,
+    SECP256K1_AFFINE_ZS, false);
+end;
+
 function TSecP256K1Curve.TSecP256K1LookupTable.GetSize: Int32;
 begin
   result := Fm_size;
@@ -1154,9 +1172,26 @@ begin
     pos := pos + (SECP256K1_FE_INTS * 2);
   end;
 
-  result := Fm_outer.CreateRawPoint(TSecP256K1FieldElement.Create(x)
-    as ISecP256K1FieldElement, TSecP256K1FieldElement.Create(y)
-    as ISecP256K1FieldElement, false);
+  result := CreatePoint(x, y);
+end;
+
+function TSecP256K1Curve.TSecP256K1LookupTable.LookupVar(index: Int32)
+  : IECPoint;
+var
+  x, y: TCryptoLibUInt32Array;
+  pos, J: Int32;
+begin
+  x := TNat256.Create();
+  y := TNat256.Create();
+  pos := index * SECP256K1_FE_INTS * 2;
+
+  for J := 0 to System.Pred(SECP256K1_FE_INTS) do
+  begin
+    x[J] := Fm_table[pos + J];
+    y[J] := Fm_table[pos + SECP256K1_FE_INTS + J];
+  end;
+
+  result := CreatePoint(x, y);
 end;
 
 end.

+ 44 - 9
CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256R1Custom.pas

@@ -212,8 +212,8 @@ type
   strict private
 
   type
-    TSecP256R1LookupTable = class sealed(TInterfacedObject,
-      ISecP256R1LookupTable, IECLookupTable)
+    TSecP256R1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecP256R1LookupTable)
 
     strict private
     var
@@ -221,16 +221,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
     public
 
       constructor Create(const outer: ISecP256R1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
 
-      function Lookup(index: Int32): IECPoint; virtual;
-
-      property size: Int32 read GetSize;
+      function Lookup(index: Int32): IECPoint; override;
+      function LookupVar(index: Int32): IECPoint; override;
 
     end;
 
@@ -1269,6 +1272,21 @@ begin
   Fm_size := size;
 end;
 
+function TSecP256R1Curve.TSecP256R1LookupTable.CreatePoint(const x,
+  y: TCryptoLibUInt32Array): IECPoint;
+var
+  XFieldElement, YFieldElement: ISecP256R1FieldElement;
+  SECP256R1_AFFINE_ZS: TCryptoLibGenericArray<IECFieldElement>;
+begin
+  SECP256R1_AFFINE_ZS := TCryptoLibGenericArray<IECFieldElement>.Create
+    (TSecP256R1FieldElement.Create(TBigInteger.One) as ISecP256R1FieldElement);
+
+  XFieldElement := TSecP256R1FieldElement.Create(x);
+  YFieldElement := TSecP256R1FieldElement.Create(y);
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement,
+    SECP256R1_AFFINE_ZS, false);
+end;
+
 function TSecP256R1Curve.TSecP256R1LookupTable.GetSize: Int32;
 begin
   result := Fm_size;
@@ -1297,9 +1315,26 @@ begin
     pos := pos + (SECP256R1_FE_INTS * 2);
   end;
 
-  result := Fm_outer.CreateRawPoint(TSecP256R1FieldElement.Create(x)
-    as ISecP256R1FieldElement, TSecP256R1FieldElement.Create(y)
-    as ISecP256R1FieldElement, false);
+  result := CreatePoint(x, y);
+end;
+
+function TSecP256R1Curve.TSecP256R1LookupTable.LookupVar(index: Int32)
+  : IECPoint;
+var
+  x, y: TCryptoLibUInt32Array;
+  pos, J: Int32;
+begin
+  x := TNat256.Create();
+  y := TNat256.Create();
+  pos := index * SECP256R1_FE_INTS * 2;
+
+  for J := 0 to System.Pred(SECP256R1_FE_INTS) do
+  begin
+    x[J] := Fm_table[pos + J];
+    y[J] := Fm_table[pos + SECP256R1_FE_INTS + J];
+  end;
+
+  result := CreatePoint(x, y);
 end;
 
 end.

+ 44 - 9
CryptoLib/src/Math/EC/Custom/Sec/ClpSecP384R1Custom.pas

@@ -210,8 +210,8 @@ type
   strict private
 
   type
-    TSecP384R1LookupTable = class sealed(TInterfacedObject,
-      ISecP384R1LookupTable, IECLookupTable)
+    TSecP384R1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecP384R1LookupTable)
 
     strict private
     var
@@ -219,16 +219,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
     public
 
       constructor Create(const outer: ISecP384R1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
 
-      function Lookup(index: Int32): IECPoint; virtual;
-
-      property size: Int32 read GetSize;
+      function Lookup(index: Int32): IECPoint; override;
+      function LookupVar(index: Int32): IECPoint; override;
 
     end;
 
@@ -1277,6 +1280,21 @@ begin
   Fm_size := size;
 end;
 
+function TSecP384R1Curve.TSecP384R1LookupTable.CreatePoint(const x,
+  y: TCryptoLibUInt32Array): IECPoint;
+var
+  XFieldElement, YFieldElement: ISecP384R1FieldElement;
+  SECP384R1_AFFINE_ZS: TCryptoLibGenericArray<IECFieldElement>;
+begin
+  SECP384R1_AFFINE_ZS := TCryptoLibGenericArray<IECFieldElement>.Create
+    (TSecP384R1FieldElement.Create(TBigInteger.One) as ISecP384R1FieldElement);
+
+  XFieldElement := TSecP384R1FieldElement.Create(x);
+  YFieldElement := TSecP384R1FieldElement.Create(y);
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement,
+    SECP384R1_AFFINE_ZS, false);
+end;
+
 function TSecP384R1Curve.TSecP384R1LookupTable.GetSize: Int32;
 begin
   result := Fm_size;
@@ -1305,9 +1323,26 @@ begin
     pos := pos + (SECP384R1_FE_INTS * 2);
   end;
 
-  result := Fm_outer.CreateRawPoint(TSecP384R1FieldElement.Create(x)
-    as ISecP384R1FieldElement, TSecP384R1FieldElement.Create(y)
-    as ISecP384R1FieldElement, false);
+  result := CreatePoint(x, y)
+end;
+
+function TSecP384R1Curve.TSecP384R1LookupTable.LookupVar(index: Int32)
+  : IECPoint;
+var
+  x, y: TCryptoLibUInt32Array;
+  pos, J: Int32;
+begin
+  x := TNat.Create(SECP384R1_FE_INTS);
+  y := TNat.Create(SECP384R1_FE_INTS);
+  pos := index * SECP384R1_FE_INTS * 2;
+
+  for J := 0 to System.Pred(SECP384R1_FE_INTS) do
+  begin
+    x[J] := Fm_table[pos + J];
+    y[J] := Fm_table[pos + SECP384R1_FE_INTS + J];
+  end;
+
+  result := CreatePoint(x, y)
 end;
 
 end.

+ 43 - 8
CryptoLib/src/Math/EC/Custom/Sec/ClpSecP521R1Custom.pas

@@ -207,7 +207,7 @@ type
   strict private
 
   type
-    TSecP521R1LookupTable = class sealed(TInterfacedObject,
+    TSecP521R1LookupTable = class sealed(TAbstractECLookupTable,
       ISecP521R1LookupTable, IECLookupTable)
 
     strict private
@@ -216,16 +216,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
     public
 
       constructor Create(const outer: ISecP521R1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
 
-      function Lookup(index: Int32): IECPoint; virtual;
-
-      property size: Int32 read GetSize;
+      function Lookup(index: Int32): IECPoint; override;
+      function LookupVar(index: Int32): IECPoint; override;
 
     end;
 
@@ -1070,6 +1073,21 @@ begin
   Fm_size := size;
 end;
 
+function TSecP521R1Curve.TSecP521R1LookupTable.CreatePoint(const x,
+  y: TCryptoLibUInt32Array): IECPoint;
+var
+  XFieldElement, YFieldElement: ISecP521R1FieldElement;
+  SECP521R1_AFFINE_ZS: TCryptoLibGenericArray<IECFieldElement>;
+begin
+  SECP521R1_AFFINE_ZS := TCryptoLibGenericArray<IECFieldElement>.Create
+    (TSecP521R1FieldElement.Create(TBigInteger.One) as ISecP521R1FieldElement);
+
+  XFieldElement := TSecP521R1FieldElement.Create(x);
+  YFieldElement := TSecP521R1FieldElement.Create(y);
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement,
+    SECP521R1_AFFINE_ZS, false);
+end;
+
 function TSecP521R1Curve.TSecP521R1LookupTable.GetSize: Int32;
 begin
   result := Fm_size;
@@ -1098,9 +1116,26 @@ begin
     pos := pos + (SECP521R1_FE_INTS * 2);
   end;
 
-  result := Fm_outer.CreateRawPoint(TSecP521R1FieldElement.Create(x)
-    as ISecP521R1FieldElement, TSecP521R1FieldElement.Create(y)
-    as ISecP521R1FieldElement, false);
+  result := CreatePoint(x, y);
+end;
+
+function TSecP521R1Curve.TSecP521R1LookupTable.LookupVar(index: Int32)
+  : IECPoint;
+var
+  x, y: TCryptoLibUInt32Array;
+  pos, J: Int32;
+begin
+  x := TNat.Create(SECP521R1_FE_INTS);
+  y := TNat.Create(SECP521R1_FE_INTS);
+  pos := index * SECP521R1_FE_INTS * 2;
+
+  for J := 0 to System.Pred(SECP521R1_FE_INTS) do
+  begin
+    x[J] := x[J] xor Fm_table[pos + J];
+    y[J] := y[J] xor Fm_table[pos + SECP521R1_FE_INTS + J];
+  end;
+
+  result := CreatePoint(x, y);
 end;
 
 end.

+ 105 - 24
CryptoLib/src/Math/EC/Custom/Sec/ClpSecT283Custom.pas

@@ -31,7 +31,7 @@ uses
   ClpBigInteger,
   ClpArrayUtils,
   ClpIECC,
-  ClpWTauNafMultiplier,
+  ClpMultipliers,
   ClpCryptoLibTypes,
   ClpECCurveConstants,
   ClpISecT283Custom;
@@ -60,8 +60,9 @@ type
     class procedure ImplMulw(x, y: UInt64; const z: TCryptoLibUInt64Array;
       zOff: Int32); static;
 
-    class procedure ImplSquare(const x, zz: TCryptoLibUInt64Array);
-      static; inline;
+    class procedure ImplSquare(const x, zz: TCryptoLibUInt64Array); static;
+
+    class procedure AddTo(const x, z: TCryptoLibUInt64Array); static; inline;
 
     class procedure Boot(); static;
     class constructor SecT283Field();
@@ -71,6 +72,10 @@ type
     class procedure AddExt(const xx, yy, zz: TCryptoLibUInt64Array);
       static; inline;
     class procedure AddOne(const x, z: TCryptoLibUInt64Array); static; inline;
+
+    class procedure HalfTrace(const x, z: TCryptoLibUInt64Array);
+      static; inline;
+
     class function FromBigInteger(const x: TBigInteger): TCryptoLibUInt64Array;
       static; inline;
 
@@ -152,6 +157,10 @@ type
 
     function Trace(): Int32; override;
 
+    function HalfTrace(): IECFieldElement; override;
+
+    function HasFastTrace(): Boolean; override;
+
     function Invert(): IECFieldElement; override;
 
     /// <summary>
@@ -249,8 +258,8 @@ type
   strict private
 
   type
-    TSecT283K1LookupTable = class sealed(TInterfacedObject,
-      ISecT283K1LookupTable, IECLookupTable)
+    TSecT283K1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecT283K1LookupTable)
 
     strict private
     var
@@ -258,16 +267,19 @@ type
       Fm_table: TCryptoLibUInt64Array;
       Fm_size: Int32;
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt64Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
     public
 
       constructor Create(const outer: ISecT283K1Curve;
         const table: TCryptoLibUInt64Array; size: Int32);
 
-      function Lookup(index: Int32): IECPoint; virtual;
-
-      property size: Int32 read GetSize;
+      function Lookup(index: Int32): IECPoint; override;
+      function LookupVar(index: Int32): IECPoint; override;
 
     end;
 
@@ -373,6 +385,15 @@ begin
   z[4] := x[4];
 end;
 
+class procedure TSecT283Field.AddTo(const x, z: TCryptoLibUInt64Array);
+begin
+  z[0] := z[0] xor x[0];
+  z[1] := z[1] xor x[1];
+  z[2] := z[2] xor x[2];
+  z[3] := z[3] xor x[3];
+  z[4] := z[4] xor x[4];
+end;
+
 class procedure TSecT283Field.Boot;
 begin
   FROOT_Z := TCryptoLibUInt64Array.Create(UInt64($0C30C30C30C30808),
@@ -380,14 +401,31 @@ begin
     UInt64($0820820820820820), UInt64($2082082));
 end;
 
+class procedure TSecT283Field.HalfTrace(const x, z: TCryptoLibUInt64Array);
+var
+  tt: TCryptoLibUInt64Array;
+  i: Int32;
+begin
+  tt := TNat.Create64(9);
+
+  TNat320.Copy64(x, z);
+  i := 1;
+
+  while i < 283 do
+  begin
+    ImplSquare(z, tt);
+    Reduce(tt, z);
+    ImplSquare(z, tt);
+    Reduce(tt, z);
+    AddTo(x, z);
+    System.Inc(i, 2);
+  end;
+end;
+
 class function TSecT283Field.FromBigInteger(const x: TBigInteger)
   : TCryptoLibUInt64Array;
-var
-  z: TCryptoLibUInt64Array;
 begin
-  z := TNat320.FromBigInteger64(x);
-  Reduce37(z, 0);
-  result := z;
+  result := TNat.FromBigInteger64(283, x);
 end;
 
 class procedure TSecT283Field.Multiply(const x, y, z: TCryptoLibUInt64Array);
@@ -400,14 +438,11 @@ begin
 end;
 
 class procedure TSecT283Field.ImplSquare(const x, zz: TCryptoLibUInt64Array);
-var
-  i: Int32;
 begin
-  for i := 0 to System.Pred(4) do
-  begin
-    TInterleave.Expand64To128(x[i], zz, i shl 1);
-  end;
-
+  TInterleave.Expand64To128(x[0], zz, 0);
+  TInterleave.Expand64To128(x[1], zz, 2);
+  TInterleave.Expand64To128(x[2], zz, 4);
+  TInterleave.Expand64To128(x[3], zz, 6);
   zz[8] := TInterleave.Expand32to64(UInt32(x[4]));
 end;
 
@@ -909,6 +944,20 @@ begin
   result := Fx;
 end;
 
+function TSecT283FieldElement.HalfTrace: IECFieldElement;
+var
+  z: TCryptoLibUInt64Array;
+begin
+  z := TNat320.Create64();
+  TSecT283Field.HalfTrace(x, z);
+  result := TSecT283FieldElement.Create(z) as ISecT283FieldElement;
+end;
+
+function TSecT283FieldElement.HasFastTrace: Boolean;
+begin
+  result := true;
+end;
+
 function TSecT283FieldElement.Invert: IECFieldElement;
 var
   z: TCryptoLibUInt64Array;
@@ -1545,6 +1594,21 @@ begin
   Fm_size := size;
 end;
 
+function TSecT283K1Curve.TSecT283K1LookupTable.CreatePoint(const x,
+  y: TCryptoLibUInt64Array): IECPoint;
+var
+  XFieldElement, YFieldElement: ISecT283FieldElement;
+  SECT283K1_AFFINE_ZS: TCryptoLibGenericArray<IECFieldElement>;
+begin
+  SECT283K1_AFFINE_ZS := TCryptoLibGenericArray<IECFieldElement>.Create
+    (TSecT283FieldElement.Create(TBigInteger.One) as ISecT283FieldElement);
+
+  XFieldElement := TSecT283FieldElement.Create(x);
+  YFieldElement := TSecT283FieldElement.Create(y);
+  result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement,
+    SECT283K1_AFFINE_ZS, false);
+end;
+
 function TSecT283K1Curve.TSecT283K1LookupTable.GetSize: Int32;
 begin
   result := Fm_size;
@@ -1573,9 +1637,26 @@ begin
     pos := pos + (SECT283K1_FE_LONGS * 2);
   end;
 
-  result := Fm_outer.CreateRawPoint(TSecT283FieldElement.Create(x)
-    as ISecT283FieldElement, TSecT283FieldElement.Create(y)
-    as ISecT283FieldElement, false);
+  result := CreatePoint(x, y);
+end;
+
+function TSecT283K1Curve.TSecT283K1LookupTable.LookupVar(index: Int32)
+  : IECPoint;
+var
+  x, y: TCryptoLibUInt64Array;
+  pos, j: Int32;
+begin
+  x := TNat320.Create64();
+  y := TNat320.Create64();
+  pos := index * SECT283K1_FE_LONGS * 2;
+
+  for j := 0 to System.Pred(SECT283K1_FE_LONGS) do
+  begin
+    x[j] := Fm_table[pos + j];
+    y[j] := Fm_table[pos + SECT283K1_FE_LONGS + j];
+  end;
+
+  result := CreatePoint(x, y);
 end;
 
 end.

+ 75 - 0
CryptoLib/src/Math/EC/Endo/ClpEndoPreCompInfo.pas

@@ -0,0 +1,75 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEndoPreCompInfo;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIECC,
+  ClpIPreCompInfo,
+  ClpIEndoPreCompInfo;
+
+type
+  TEndoPreCompInfo = class sealed(TInterfacedObject, IPreCompInfo,
+    IEndoPreCompInfo)
+
+  strict private
+  var
+    FEndomorphism: IECEndomorphism;
+    FMappedPoint: IECPoint;
+
+    function GetEndomorphism: IECEndomorphism; inline;
+    procedure SetEndomorphism(const value: IECEndomorphism); inline;
+
+    function GetMappedPoint: IECPoint; inline;
+    procedure SetMappedPoint(const value: IECPoint); inline;
+
+  public
+
+    property Endomorphism: IECEndomorphism read GetEndomorphism
+      write SetEndomorphism;
+    property MappedPoint: IECPoint read GetMappedPoint write SetMappedPoint;
+  end;
+
+implementation
+
+{ TEndoPreCompInfo }
+
+function TEndoPreCompInfo.GetEndomorphism: IECEndomorphism;
+begin
+  result := FEndomorphism;
+end;
+
+function TEndoPreCompInfo.GetMappedPoint: IECPoint;
+begin
+  result := FMappedPoint;
+end;
+
+procedure TEndoPreCompInfo.SetEndomorphism(const value: IECEndomorphism);
+begin
+  FEndomorphism := value;
+end;
+
+procedure TEndoPreCompInfo.SetMappedPoint(const value: IECPoint);
+begin
+  FMappedPoint := value;
+end;
+
+end.

+ 92 - 0
CryptoLib/src/Math/EC/Endo/ClpGlvTypeAEndomorphism.pas

@@ -0,0 +1,92 @@
+{ *********************************************************************************** }
+{ *                              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 ClpGlvTypeAEndomorphism;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpCryptoLibTypes,
+  ClpBigInteger,
+  ClpECCompUtilities,
+  ClpScaleYNegateXPointMap,
+  ClpIGlvTypeAEndomorphism,
+  ClpIECC,
+  ClpIGlvTypeAParameters,
+  ClpIGlvEndomorphism;
+
+type
+  TGlvTypeAEndomorphism = class(TInterfacedObject, IECEndomorphism,
+    IGlvEndomorphism, IGlvTypeAEndomorphism)
+
+  strict private
+    function GetHasEfficientPointMap: Boolean; virtual;
+    function GetPointMap: IECPointMap; virtual;
+
+  strict protected
+  var
+    FParameters: IGlvTypeAParameters;
+    FPointMap: IECPointMap;
+
+  public
+    constructor Create(const curve: IECCurve;
+      const parameters: IGlvTypeAParameters);
+
+    function DecomposeScalar(const k: TBigInteger)
+      : TCryptoLibGenericArray<TBigInteger>; virtual;
+
+    property PointMap: IECPointMap read GetPointMap;
+    property HasEfficientPointMap: Boolean read GetHasEfficientPointMap;
+  end;
+
+implementation
+
+{ TGlvTypeAEndomorphism }
+
+constructor TGlvTypeAEndomorphism.Create(const curve: IECCurve;
+  const parameters: IGlvTypeAParameters);
+begin
+  Inherited Create();
+  (*
+    * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way
+    * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the
+    * endomorphism is being used with.
+  *)
+  FParameters := parameters;
+  FPointMap := TScaleYNegateXPointMap.Create
+    (curve.FromBigInteger(parameters.I));
+end;
+
+function TGlvTypeAEndomorphism.DecomposeScalar(const k: TBigInteger)
+  : TCryptoLibGenericArray<TBigInteger>;
+begin
+  Result := TEndoUtilities.DecomposeScalar(FParameters.SplitParams, k);
+end;
+
+function TGlvTypeAEndomorphism.GetHasEfficientPointMap: Boolean;
+begin
+  Result := true;
+end;
+
+function TGlvTypeAEndomorphism.GetPointMap: IECPointMap;
+begin
+  Result := FPointMap;
+end;
+
+end.

+ 81 - 0
CryptoLib/src/Math/EC/Endo/ClpGlvTypeAParameters.pas

@@ -0,0 +1,81 @@
+{ *********************************************************************************** }
+{ *                              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 ClpGlvTypeAParameters;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIGlvTypeAParameters,
+  ClpIScalarSplitParameters,
+  ClpCryptoLibTypes;
+
+type
+  TGlvTypeAParameters = class sealed(TInterfacedObject, IGlvTypeAParameters)
+
+  strict private
+  var
+    FI, Flambda: TBigInteger;
+    FsplitParams: IScalarSplitParameters;
+
+    function GetLambda: TBigInteger; inline;
+    function GetI: TBigInteger; inline;
+    function GetSplitParams: IScalarSplitParameters; inline;
+
+  public
+
+    constructor Create(const I, lambda: TBigInteger;
+      const splitParams: IScalarSplitParameters);
+
+    property lambda: TBigInteger read GetLambda;
+    property I: TBigInteger read GetI;
+    property splitParams: IScalarSplitParameters read GetSplitParams;
+
+  end;
+
+implementation
+
+{ TGlvTypeAParameters }
+
+constructor TGlvTypeAParameters.Create(const I, lambda: TBigInteger;
+  const splitParams: IScalarSplitParameters);
+begin
+  Inherited Create();
+  FI := I;
+  Flambda := lambda;
+  FsplitParams := splitParams;
+end;
+
+function TGlvTypeAParameters.GetI: TBigInteger;
+begin
+  Result := FI;
+end;
+
+function TGlvTypeAParameters.GetLambda: TBigInteger;
+begin
+  Result := Flambda;
+end;
+
+function TGlvTypeAParameters.GetSplitParams: IScalarSplitParameters;
+begin
+  Result := FsplitParams;
+end;
+
+end.

+ 4 - 48
CryptoLib/src/Math/EC/Endo/ClpGlvTypeBEndomorphism.pas

@@ -28,7 +28,8 @@ uses
   ClpIGlvTypeBEndomorphism,
   ClpIECC,
   ClpIGlvTypeBParameters,
-  ClpIGlvEndomorphism;
+  ClpIGlvEndomorphism,
+  ClpECCompUtilities;
 
 type
   TGlvTypeBEndomorphism = class(TInterfacedObject, IECEndomorphism,
@@ -43,13 +44,10 @@ type
     FParameters: IGlvTypeBParameters;
     FPointMap: IECPointMap;
 
-    function CalculateB(const k, g: TBigInteger; t: Int32)
-      : TBigInteger; virtual;
-
   public
     constructor Create(const curve: IECCurve;
       const parameters: IGlvTypeBParameters);
-    destructor Destroy; override;
+
     function DecomposeScalar(const k: TBigInteger)
       : TCryptoLibGenericArray<TBigInteger>; virtual;
 
@@ -61,31 +59,6 @@ implementation
 
 { TGlvTypeBEndomorphism }
 
-function TGlvTypeBEndomorphism.CalculateB(const k, g: TBigInteger; t: Int32)
-  : TBigInteger;
-var
-  negative, extra: Boolean;
-  b: TBigInteger;
-begin
-  negative := (g.SignValue < 0);
-  b := k.Multiply(g.Abs());
-  extra := b.TestBit(t - 1);
-  b := b.ShiftRight(t);
-  if (extra) then
-  begin
-    b := b.Add(TBigInteger.One);
-  end;
-
-  if negative then
-  begin
-    Result := b.Negate();
-  end
-  else
-  begin
-    Result := b;
-  end;
-end;
-
 constructor TGlvTypeBEndomorphism.Create(const curve: IECCurve;
   const parameters: IGlvTypeBParameters);
 begin
@@ -101,25 +74,8 @@ end;
 
 function TGlvTypeBEndomorphism.DecomposeScalar(const k: TBigInteger)
   : TCryptoLibGenericArray<TBigInteger>;
-var
-  bits: Int32;
-  b1, b2, a, b: TBigInteger;
-  p: IGlvTypeBParameters;
-begin
-  bits := FParameters.bits;
-  b1 := CalculateB(k, FParameters.G1, bits);
-  b2 := CalculateB(k, FParameters.G2, bits);
-
-  p := FParameters;
-  a := k.subtract((b1.Multiply(p.V1A)).Add(b2.Multiply(p.V2A)));
-  b := (b1.Multiply(p.V1B)).Add(b2.Multiply(p.V2B)).Negate();
-
-  Result := TCryptoLibGenericArray<TBigInteger>.Create(a, b);
-end;
-
-destructor TGlvTypeBEndomorphism.Destroy;
 begin
-  inherited Destroy;
+  Result := TEndoUtilities.DecomposeScalar(FParameters.SplitParams, k);
 end;
 
 function TGlvTypeBEndomorphism.GetHasEfficientPointMap: Boolean;

+ 16 - 89
CryptoLib/src/Math/EC/Endo/ClpGlvTypeBParameters.pas

@@ -24,48 +24,29 @@ interface
 uses
   ClpBigInteger,
   ClpIGlvTypeBParameters,
+  ClpIScalarSplitParameters,
   ClpCryptoLibTypes;
 
-resourcestring
-  SInvalidParameters = '"%s" must consist of exactly 2 (initialized) values';
-
 type
   TGlvTypeBParameters = class sealed(TInterfacedObject, IGlvTypeBParameters)
 
   strict private
-    function GetG1: TBigInteger; inline;
-    function GetG2: TBigInteger; inline;
-    function GetV1A: TBigInteger; inline;
-    function GetV1B: TBigInteger; inline;
-    function GetV2A: TBigInteger; inline;
-    function GetV2B: TBigInteger; inline;
+  var
+    Fbeta, Flambda: TBigInteger;
+    FsplitParams: IScalarSplitParameters;
+
     function GetLambda: TBigInteger; inline;
     function GetBeta: TBigInteger; inline;
-    function GetBits: Int32; inline;
-
-    class procedure CheckVector(const v: TCryptoLibGenericArray<TBigInteger>;
-      const name: String); static;
-
-  strict protected
-    Fbeta, Flambda, Fg1, Fg2, Fv1A, Fv1B, Fv2A, Fv2B: TBigInteger;
-    Fbits: Int32;
+    function GetSplitParams: IScalarSplitParameters; inline;
 
   public
-    constructor Create(const beta, lambda: TBigInteger;
-      const v1, v2: TCryptoLibGenericArray<TBigInteger>;
-      const g1, g2: TBigInteger; bits: Int32);
 
-    destructor Destroy; override;
+    constructor Create(const beta, lambda: TBigInteger;
+      const splitParams: IScalarSplitParameters);
 
-    property g1: TBigInteger read GetG1;
-    property g2: TBigInteger read GetG2;
-    property V1A: TBigInteger read GetV1A;
-    property V1B: TBigInteger read GetV1B;
-    property V2A: TBigInteger read GetV2A;
-    property V2B: TBigInteger read GetV2B;
     property lambda: TBigInteger read GetLambda;
     property beta: TBigInteger read GetBeta;
-    property bits: Int32 read GetBits;
+    property splitParams: IScalarSplitParameters read GetSplitParams;
 
   end;
 
@@ -73,67 +54,13 @@ implementation
 
 { TGlvTypeBParameters }
 
-class procedure TGlvTypeBParameters.CheckVector
-  (const v: TCryptoLibGenericArray<TBigInteger>; const name: String);
-begin
-  if ((v = Nil) or (System.length(v) <> 2) or (not v[0].IsInitialized) or
-    (not v[1].IsInitialized)) then
-  begin
-    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidParameters, [name]);
-  end;
-end;
-
 constructor TGlvTypeBParameters.Create(const beta, lambda: TBigInteger;
-  const v1, v2: TCryptoLibGenericArray<TBigInteger>; const g1, g2: TBigInteger;
-  bits: Int32);
+  const splitParams: IScalarSplitParameters);
 begin
-  CheckVector(v1, 'v1');
-  CheckVector(v2, 'v2');
-
+  Inherited Create();
   Fbeta := beta;
   Flambda := lambda;
-  Fv1A := v1[0];
-  Fv1B := v1[1];
-  Fv2A := v2[0];
-  Fv2B := v2[1];
-  Fg1 := g1;
-  Fg2 := g2;
-  Fbits := bits;
-end;
-
-destructor TGlvTypeBParameters.Destroy;
-begin
-  inherited Destroy;
-end;
-
-function TGlvTypeBParameters.GetG1: TBigInteger;
-begin
-  Result := Fg1;
-end;
-
-function TGlvTypeBParameters.GetG2: TBigInteger;
-begin
-  Result := Fg2;
-end;
-
-function TGlvTypeBParameters.GetV1A: TBigInteger;
-begin
-  Result := Fv1A;
-end;
-
-function TGlvTypeBParameters.GetV1B: TBigInteger;
-begin
-  Result := Fv1B;
-end;
-
-function TGlvTypeBParameters.GetV2A: TBigInteger;
-begin
-  Result := Fv2A;
-end;
-
-function TGlvTypeBParameters.GetV2B: TBigInteger;
-begin
-  Result := Fv2B;
+  FsplitParams := splitParams;
 end;
 
 function TGlvTypeBParameters.GetBeta: TBigInteger;
@@ -141,14 +68,14 @@ begin
   Result := Fbeta;
 end;
 
-function TGlvTypeBParameters.GetBits: Int32;
+function TGlvTypeBParameters.GetLambda: TBigInteger;
 begin
-  Result := Fbits;
+  Result := Flambda;
 end;
 
-function TGlvTypeBParameters.GetLambda: TBigInteger;
+function TGlvTypeBParameters.GetSplitParams: IScalarSplitParameters;
 begin
-  Result := Flambda;
+  Result := FsplitParams;
 end;
 
 end.

+ 131 - 0
CryptoLib/src/Math/EC/Endo/ClpScalarSplitParameters.pas

@@ -0,0 +1,131 @@
+{ *********************************************************************************** }
+{ *                              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 ClpScalarSplitParameters;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIScalarSplitParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidParameters = '"%s" must consist of exactly 2 (initialized) values';
+
+type
+  TScalarSplitParameters = class sealed(TInterfacedObject,
+    IScalarSplitParameters)
+
+  strict private
+    function GetG1: TBigInteger; inline;
+    function GetG2: TBigInteger; inline;
+    function GetV1A: TBigInteger; inline;
+    function GetV1B: TBigInteger; inline;
+    function GetV2A: TBigInteger; inline;
+    function GetV2B: TBigInteger; inline;
+    function GetBits: Int32; inline;
+
+    class procedure CheckVector(const v: TCryptoLibGenericArray<TBigInteger>;
+      const name: String); static;
+
+  strict protected
+    Fg1, Fg2, Fv1A, Fv1B, Fv2A, Fv2B: TBigInteger;
+    Fbits: Int32;
+
+  public
+    constructor Create(const v1, v2: TCryptoLibGenericArray<TBigInteger>;
+      const g1, g2: TBigInteger; bits: Int32);
+
+    property g1: TBigInteger read GetG1;
+    property g2: TBigInteger read GetG2;
+    property V1A: TBigInteger read GetV1A;
+    property V1B: TBigInteger read GetV1B;
+    property V2A: TBigInteger read GetV2A;
+    property V2B: TBigInteger read GetV2B;
+    property bits: Int32 read GetBits;
+
+  end;
+
+implementation
+
+{ TScalarSplitParameters }
+
+class procedure TScalarSplitParameters.CheckVector
+  (const v: TCryptoLibGenericArray<TBigInteger>; const name: String);
+begin
+  if ((v = Nil) or (System.length(v) <> 2) or (not v[0].IsInitialized) or
+    (not v[1].IsInitialized)) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidParameters, [name]);
+  end;
+end;
+
+constructor TScalarSplitParameters.Create(const v1,
+  v2: TCryptoLibGenericArray<TBigInteger>; const g1, g2: TBigInteger;
+  bits: Int32);
+begin
+  CheckVector(v1, 'v1');
+  CheckVector(v2, 'v2');
+
+  Fv1A := v1[0];
+  Fv1B := v1[1];
+  Fv2A := v2[0];
+  Fv2B := v2[1];
+  Fg1 := g1;
+  Fg2 := g2;
+  Fbits := bits;
+end;
+
+function TScalarSplitParameters.GetG1: TBigInteger;
+begin
+  Result := Fg1;
+end;
+
+function TScalarSplitParameters.GetG2: TBigInteger;
+begin
+  Result := Fg2;
+end;
+
+function TScalarSplitParameters.GetV1A: TBigInteger;
+begin
+  Result := Fv1A;
+end;
+
+function TScalarSplitParameters.GetV1B: TBigInteger;
+begin
+  Result := Fv1B;
+end;
+
+function TScalarSplitParameters.GetV2A: TBigInteger;
+begin
+  Result := Fv2A;
+end;
+
+function TScalarSplitParameters.GetV2B: TBigInteger;
+begin
+  Result := Fv2B;
+end;
+
+function TScalarSplitParameters.GetBits: Int32;
+begin
+  Result := Fbits;
+end;
+
+end.

+ 0 - 101
CryptoLib/src/Math/EC/Multiplier/ClpAbstractECMultiplier.pas

@@ -1,101 +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 ClpAbstractECMultiplier;
-
-{$I ..\..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  ClpBigInteger,
-  ClpIECC,
-  ClpIAbstractECMultiplier,
-  ClpECAlgorithms;
-
-type
-  TAbstractECMultiplier = class abstract(TInterfacedObject,
-    IAbstractECMultiplier, IECMultiplier)
-
-  strict protected
-
-    function CheckResult(const p: IECPoint): IECPoint; virtual;
-    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
-      : IECPoint; virtual; abstract;
-
-  public
-
-    constructor Create();
-    destructor Destroy; override;
-    function Multiply(const p: IECPoint; const k: TBigInteger)
-      : IECPoint; virtual;
-
-  end;
-
-implementation
-
-{ TAbstractECMultiplier }
-
-function TAbstractECMultiplier.CheckResult(const p: IECPoint): IECPoint;
-begin
-  result := TECAlgorithms.ImplCheckResult(p);
-end;
-
-constructor TAbstractECMultiplier.Create;
-begin
-  Inherited Create();
-end;
-
-destructor TAbstractECMultiplier.Destroy;
-begin
-  inherited Destroy;
-end;
-
-function TAbstractECMultiplier.Multiply(const p: IECPoint; const k: TBigInteger)
-  : IECPoint;
-var
-  positive: IECPoint;
-  sign: Int32;
-begin
-
-  sign := k.SignValue;
-  if ((sign = 0) or (p.IsInfinity)) then
-  begin
-    result := p.Curve.Infinity;
-    Exit;
-  end;
-
-  positive := MultiplyPositive(p, k.Abs());
-
-  if sign > 0 then
-  begin
-    result := positive
-  end
-  else
-  begin
-    result := positive.Negate();
-  end;
-
-  // /*
-  // * Although the various multipliers ought not to produce invalid output under normal
-  // * circumstances, a final check here is advised to guard against fault attacks.
-  // */
-  result := CheckResult(result);
-
-end;
-
-end.

+ 0 - 130
CryptoLib/src/Math/EC/Multiplier/ClpFixedPointCombMultiplier.pas

@@ -1,130 +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 ClpFixedPointCombMultiplier;
-
-{$I ..\..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  ClpBits,
-  ClpBigInteger,
-  ClpNat,
-  ClpCryptoLibTypes,
-  ClpIECC,
-  ClpFixedPointUtilities,
-  ClpIFixedPointPreCompInfo,
-  ClpAbstractECMultiplier,
-  ClpIFixedPointCombMultiplier;
-
-resourcestring
-  SInvalidComputation =
-    'Fixed-Point Comb Doesn''t Support Scalars Larger Than The Curve Order';
-
-type
-  TFixedPointCombMultiplier = class sealed(TAbstractECMultiplier,
-    IFixedPointCombMultiplier)
-
-  strict protected
-    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
-      : IECPoint; override;
-
-  public
-    constructor Create();
-    destructor Destroy; override;
-
-  end;
-
-implementation
-
-{ TFixedPointCombMultiplier }
-
-constructor TFixedPointCombMultiplier.Create;
-begin
-  Inherited Create();
-end;
-
-destructor TFixedPointCombMultiplier.Destroy;
-begin
-  inherited Destroy;
-end;
-
-function TFixedPointCombMultiplier.MultiplyPositive(const p: IECPoint;
-  const k: TBigInteger): IECPoint;
-var
-  c: IECCurve;
-  R, add: IECPoint;
-  size, width, d, top, i, j, fullComb: Int32;
-  secretIndex, secretBit: UInt32;
-  info: IFixedPointPreCompInfo;
-  lookupTable: IECLookupTable;
-  LK: TCryptoLibUInt32Array;
-begin
-  c := p.Curve;
-  size := TFixedPointUtilities.GetCombSize(c);
-  if (k.BitLength > size) then
-  begin
-    // /*
-    // * TODO The comb works best when the scalars are less than the (possibly unknown) order.
-    // * Still, if we want to handle larger scalars, we could allow customization of the comb
-    // * size, or alternatively we could deal with the 'extra' bits either by running the comb
-    // * multiple times as necessary, or by using an alternative multiplier as prelude.
-    // */
-    raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidComputation);
-  end;
-
-  info := TFixedPointUtilities.Precompute(p);
-  lookupTable := info.lookupTable;
-  width := info.width;
-
-  d := (size + width - 1) div width;
-
-  R := c.Infinity;
-  fullComb := d * width;
-  LK := TNat.FromBigInteger(fullComb, k);
-
-  top := fullComb - 1;
-
-  for i := 0 to System.Pred(d) do
-  begin
-
-    secretIndex := 0;
-
-    j := (top - i);
-
-    while j >= 0 do
-    begin
-
-      secretBit := LK[TBits.Asr32(j, 5)] shr (j and $1F);
-      secretIndex := secretIndex xor (secretBit shr 1);
-      secretIndex := secretIndex shl 1;
-      secretIndex := secretIndex xor secretBit;
-
-      System.Dec(j, d);
-    end;
-
-    add := lookupTable.Lookup(Int32(secretIndex));
-    R := R.TwicePlus(add);
-
-  end;
-
-  Result := R.add(info.Offset);
-
-end;
-
-end.

+ 0 - 219
CryptoLib/src/Math/EC/Multiplier/ClpFixedPointUtilities.pas

@@ -1,219 +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 ClpFixedPointUtilities;
-
-{$I ..\..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  SysUtils,
-  ClpBigInteger,
-  ClpCryptoLibTypes,
-  ClpIPreCompInfo,
-  ClpIPreCompCallback,
-  ClpFixedPointPreCompInfo,
-  ClpIFixedPointPreCompInfo,
-  ClpIECC;
-
-type
-  TFixedPointUtilities = class sealed(TObject)
-  strict private
-
-  type
-    IFixedPointCallback = interface(IPreCompCallback)
-      ['{E6DFE8D3-A890-4568-AA4A-3D8BC6AF16E9}']
-
-    end;
-
-  type
-    TFixedPointCallback = class(TInterfacedObject, IPreCompCallback,
-      IFixedPointCallback)
-
-    strict private
-    var
-      Fm_p: IECPoint;
-
-    public
-      constructor Create(const p: IECPoint);
-
-      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
-
-    end;
-
-  const
-    PRECOMP_NAME: String = 'bc_fixed_point';
-
-    class function CheckExisting(const existingFP: IFixedPointPreCompInfo;
-      n: Int32): Boolean; static; inline;
-
-    class function CheckTable(const table: IECLookupTable; n: Int32): Boolean;
-      static; inline;
-
-  public
-
-    class function GetFixedPointPreCompInfo(const preCompInfo: IPreCompInfo)
-      : IFixedPointPreCompInfo; static; inline;
-
-    class function GetCombSize(const c: IECCurve): Int32; static; inline;
-
-    class function Precompute(const p: IECPoint)
-      : IFixedPointPreCompInfo; static;
-  end;
-
-implementation
-
-{ TFixedPointUtilities }
-
-class function TFixedPointUtilities.CheckTable(const table: IECLookupTable;
-  n: Int32): Boolean;
-begin
-  result := (table <> Nil) and (table.Size >= n);
-end;
-
-class function TFixedPointUtilities.CheckExisting(const existingFP
-  : IFixedPointPreCompInfo; n: Int32): Boolean;
-begin
-  result := (existingFP <> Nil) and CheckTable(existingFP.LookUpTable, n);
-end;
-
-class function TFixedPointUtilities.GetCombSize(const c: IECCurve): Int32;
-var
-  order: TBigInteger;
-begin
-  order := c.order;
-  if (not(order.IsInitialized)) then
-  begin
-    result := c.FieldSize + 1;
-  end
-  else
-  begin
-    result := order.BitLength;
-  end;
-end;
-
-class function TFixedPointUtilities.GetFixedPointPreCompInfo(const preCompInfo
-  : IPreCompInfo): IFixedPointPreCompInfo;
-begin
-  result := preCompInfo as IFixedPointPreCompInfo;
-end;
-
-class function TFixedPointUtilities.Precompute(const p: IECPoint)
-  : IFixedPointPreCompInfo;
-var
-  c: IECCurve;
-begin
-  c := p.Curve;
-
-  result := c.Precompute(p, PRECOMP_NAME, TFixedPointCallback.Create(p)
-    as IFixedPointCallback) as IFixedPointPreCompInfo;
-end;
-
-{ TFixedPointUtilities.TFixedPointCallback }
-
-constructor TFixedPointUtilities.TFixedPointCallback.Create(const p: IECPoint);
-begin
-  Inherited Create();
-  Fm_p := p;
-end;
-
-function TFixedPointUtilities.TFixedPointCallback.Precompute(const existing
-  : IPreCompInfo): IPreCompInfo;
-var
-  bit, bits, minWidth, n, d, i, step: Int32;
-  existingFP: IFixedPointPreCompInfo;
-  pow2Table, LookUpTable: TCryptoLibGenericArray<IECPoint>;
-  pow2: IECPoint;
-  c: IECCurve;
-  tempResult: IFixedPointPreCompInfo;
-begin
-  if Supports(existing, IFixedPointPreCompInfo) then
-  begin
-    existingFP := existing as IFixedPointPreCompInfo;
-  end
-  else
-  begin
-    existingFP := Nil;
-  end;
-
-  c := Fm_p.Curve;
-  bits := TFixedPointUtilities.GetCombSize(c);
-  if bits > 250 then
-  begin
-    minWidth := 6
-  end
-  else
-  begin
-    minWidth := 5
-  end;
-  n := 1 shl minWidth;
-
-  if (CheckExisting(existingFP, n)) then
-  begin
-    result := existingFP;
-    Exit;
-  end;
-
-  d := (bits + minWidth - 1) div minWidth;
-
-  System.SetLength(pow2Table, minWidth + 1);
-
-  pow2Table[0] := Fm_p;
-  for i := 1 to System.Pred(minWidth) do
-  begin
-    pow2Table[i] := pow2Table[i - 1].TimesPow2(d);
-  end;
-
-  // This will be the 'offset' value
-  pow2Table[minWidth] := pow2Table[0].Subtract(pow2Table[1]);
-
-  c.NormalizeAll(pow2Table);
-
-  System.SetLength(LookUpTable, n);
-  LookUpTable[0] := pow2Table[0];
-
-  bit := minWidth - 1;
-  while bit >= 0 do
-  begin
-    pow2 := pow2Table[bit];
-
-    step := 1 shl bit;
-
-    i := step;
-
-    while i < n do
-    begin
-      LookUpTable[i] := LookUpTable[i - step].Add(pow2);
-
-      System.Inc(i, step shl 1);
-    end;
-
-    System.Dec(bit);
-  end;
-
-  c.NormalizeAll(LookUpTable);
-
-  tempResult := TFixedPointPreCompInfo.Create();
-  tempResult.LookUpTable := c.CreateCacheSafeLookupTable(LookUpTable, 0,
-    System.length(LookUpTable));
-  tempResult.Offset := pow2Table[minWidth];
-  tempResult.Width := minWidth;
-  result := tempResult;
-end;
-
-end.

+ 0 - 106
CryptoLib/src/Math/EC/Multiplier/ClpGlvMultiplier.pas

@@ -1,106 +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 ClpGlvMultiplier;
-
-{$I ..\..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  ClpSetWeakRef,
-  ClpAbstractECMultiplier,
-  ClpIECC,
-  ClpIGlvEndomorphism,
-  ClpCryptoLibTypes,
-  ClpECAlgorithms,
-  ClpBigInteger,
-  ClpIGlvMultiplier;
-
-resourcestring
-  SCurveUnknownGroupOrder = 'Need Curve With Known Group Order, "curve"';
-
-type
-  TGlvMultiplier = class(TAbstractECMultiplier, IGlvMultiplier)
-
-  strict protected
-  var
-    Fcurve: IECCurve;
-    FglvEndomorphism: IGlvEndomorphism;
-
-    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
-      : IECPoint; override;
-
-  public
-    constructor Create(const curve: IECCurve;
-      const glvEndomorphism: IGlvEndomorphism);
-    destructor Destroy; override;
-
-  end;
-
-implementation
-
-{ TGlvMultiplier }
-
-constructor TGlvMultiplier.Create(const curve: IECCurve;
-  const glvEndomorphism: IGlvEndomorphism);
-begin
-  inherited Create();
-  if ((curve = Nil) or (not(curve.Order.IsInitialized))) then
-  begin
-    raise EArgumentCryptoLibException.CreateRes(@SCurveUnknownGroupOrder);
-  end;
-
-  // Fcurve := curve;
-  TSetWeakRef.SetWeakReference(@Fcurve, curve);
-  FglvEndomorphism := glvEndomorphism;
-end;
-
-destructor TGlvMultiplier.Destroy;
-begin
-  TSetWeakRef.SetWeakReference(@Fcurve, Nil);
-  inherited Destroy;
-end;
-
-function TGlvMultiplier.MultiplyPositive(const p: IECPoint;
-  const k: TBigInteger): IECPoint;
-var
-  n, a, b: TBigInteger;
-  ab: TCryptoLibGenericArray<TBigInteger>;
-  pointMap: IECPointMap;
-begin
-  if (not(Fcurve.Equals(p.curve))) then
-  begin
-    raise EInvalidOperationCryptoLibException.Create('');
-  end;
-
-  n := p.curve.Order;
-  ab := FglvEndomorphism.DecomposeScalar(k.&Mod(n));
-  a := ab[0];
-  b := ab[1];
-
-  pointMap := FglvEndomorphism.pointMap;
-  if (FglvEndomorphism.HasEfficientPointMap) then
-  begin
-    Result := TECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap, b);
-    Exit;
-  end;
-
-  Result := TECAlgorithms.ImplShamirsTrickWNaf(p, a, pointMap.Map(p), b);
-end;
-
-end.

+ 621 - 0
CryptoLib/src/Math/EC/Multiplier/ClpMultipliers.pas

@@ -0,0 +1,621 @@
+{ *********************************************************************************** }
+{ *                              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 ClpMultipliers;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpBigInteger,
+  ClpBits,
+  ClpNat,
+  ClpTNaf,
+  ClpIECC,
+  ClpIGlvEndomorphism,
+  ClpIFixedPointPreCompInfo,
+  ClpIWTauNafPreCompInfo,
+  ClpWTauNafPreCompInfo,
+  ClpIZTauElement,
+  ClpIPreCompInfo,
+  ClpIPreCompCallBack,
+  ClpIMultipliers,
+  ClpIWNafPreCompInfo,
+  ClpECCompUtilities,
+  ClpSetWeakRef,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidComputation =
+    'Fixed-Point Comb Doesn''t Support Scalars Larger Than The Curve Order';
+  SCurveUnknownGroupOrder = 'Need Curve With Known Group Order, "curve"';
+  SInCompatiblePoint = 'Only AbstractF2mPoint can be used in WTauNafMultiplier';
+
+type
+  TAbstractECMultiplier = class abstract(TInterfacedObject,
+    IAbstractECMultiplier, IECMultiplier)
+
+  strict protected
+
+    function CheckResult(const p: IECPoint): IECPoint; virtual;
+    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
+      : IECPoint; virtual; abstract;
+
+  public
+
+    constructor Create();
+    function Multiply(const p: IECPoint; const k: TBigInteger)
+      : IECPoint; virtual;
+
+  end;
+
+type
+  TFixedPointCombMultiplier = class sealed(TAbstractECMultiplier,
+    IFixedPointCombMultiplier)
+
+  strict protected
+    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
+      : IECPoint; override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+  TGlvMultiplier = class(TAbstractECMultiplier, IGlvMultiplier)
+
+  strict protected
+  var
+    Fcurve: IECCurve;
+    FglvEndomorphism: IGlvEndomorphism;
+
+    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
+      : IECPoint; override;
+
+  public
+    constructor Create(const curve: IECCurve;
+      const glvEndomorphism: IGlvEndomorphism);
+    destructor Destroy; override;
+
+  end;
+
+type
+
+  /// <summary>
+  /// Class implementing the WNAF (Window Non-Adjacent Form) multiplication
+  /// algorithm.
+  /// </summary>
+  TWNafL2RMultiplier = class(TAbstractECMultiplier, IWNafL2RMultiplier)
+
+  strict protected
+    // /**
+    // * Multiplies <code>this</code> by an integer <code>k</code> using the
+    // * Window NAF method.
+    // * @param k The integer by which <code>this</code> is multiplied.
+    // * @return A new <code>ECPoint</code> which equals <code>this</code>
+    // * multiplied by <code>k</code>.
+    // */
+    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
+      : IECPoint; override;
+
+  public
+
+    constructor Create();
+
+  end;
+
+type
+  /// **
+  // * Class implementing the WTNAF (Window
+  // * <code>&#964;</code>-adic Non-Adjacent Form) algorithm.
+  // */
+  TWTauNafMultiplier = class(TAbstractECMultiplier, IWTauNafMultiplier)
+
+  strict private
+    // TODO Create WTauNafUtilities class and move various functionality into it
+
+  type
+    IWTauNafCallback = interface(IPreCompCallback)
+      ['{4D6F7B4A-B925-42C9-8D60-B7F24632EDC1}']
+
+    end;
+
+  type
+    TWTauNafCallback = class(TInterfacedObject, IPreCompCallback,
+      IWTauNafCallback)
+
+    strict private
+    var
+      Fm_p: IAbstractF2mPoint;
+      Fm_a: ShortInt;
+
+    public
+      constructor Create(const p: IAbstractF2mPoint; a: ShortInt);
+
+      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
+
+    end;
+
+  const
+    PRECOMP_NAME: String = 'bc_wtnaf';
+
+    // /**
+    // * Multiplies an AbstractF2mPoint
+    // * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code> using
+    // * the <code>&#964;</code>-adic NAF (TNAF) method.
+    // * @param p The AbstractF2mPoint to multiply.
+    // * @param lambda The element <code>&#955;</code> of
+    // * <code><b>Z</b>[&#964;]</code> of which to compute the
+    // * <code>[&#964;]</code>-adic NAF.
+    // * @return <code>p</code> multiplied by <code>&#955;</code>.
+    // */
+    function MultiplyWTnaf(const p: IAbstractF2mPoint;
+      const lambda: IZTauElement; a, mu: ShortInt): IAbstractF2mPoint; inline;
+
+    // /**
+    // * Multiplies an AbstractF2mPoint
+    // * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
+    // * using the window <code>&#964;</code>-adic NAF (TNAF) method, given the
+    // * WTNAF of <code>&#955;</code>.
+    // * @param p The AbstractF2mPoint to multiply.
+    // * @param u The the WTNAF of <code>&#955;</code>..
+    // * @return <code>&#955; * p</code>
+    // */
+    class function MultiplyFromWTnaf(const p: IAbstractF2mPoint;
+      const u: TCryptoLibShortIntArray): IAbstractF2mPoint; static;
+
+  strict protected
+    // /**
+    // * Multiplies an AbstractF2mPoint
+    // * by <code>k</code> using the reduced <code>&#964;</code>-adic NAF (RTNAF)
+    // * method.
+    // * @param p The AbstractF2mPoint to multiply.
+    // * @param k The integer by which to multiply <code>k</code>.
+    // * @return <code>p</code> multiplied by <code>k</code>.
+    // */
+    function MultiplyPositive(const point: IECPoint; const k: TBigInteger)
+      : IECPoint; override;
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+uses
+  ClpECAlgorithms; // included here to avoid circular dependency :)
+
+{ TAbstractECMultiplier }
+
+function TAbstractECMultiplier.CheckResult(const p: IECPoint): IECPoint;
+begin
+  result := TECAlgorithms.ImplCheckResult(p);
+end;
+
+constructor TAbstractECMultiplier.Create;
+begin
+  Inherited Create();
+end;
+
+function TAbstractECMultiplier.Multiply(const p: IECPoint; const k: TBigInteger)
+  : IECPoint;
+var
+  positive: IECPoint;
+  sign: Int32;
+begin
+
+  sign := k.SignValue;
+  if ((sign = 0) or (p.IsInfinity)) then
+  begin
+    result := p.curve.Infinity;
+    Exit;
+  end;
+
+  positive := MultiplyPositive(p, k.Abs());
+
+  if sign > 0 then
+  begin
+    result := positive
+  end
+  else
+  begin
+    result := positive.Negate();
+  end;
+
+  // /*
+  // * Although the various multipliers ought not to produce invalid output under normal
+  // * circumstances, a final check here is advised to guard against fault attacks.
+  // */
+  result := CheckResult(result);
+
+end;
+
+{ TFixedPointCombMultiplier }
+
+constructor TFixedPointCombMultiplier.Create;
+begin
+  Inherited Create();
+end;
+
+function TFixedPointCombMultiplier.MultiplyPositive(const p: IECPoint;
+  const k: TBigInteger): IECPoint;
+var
+  c: IECCurve;
+  R, add: IECPoint;
+  size, width, d, top, i, j, fullComb: Int32;
+  secretIndex, secretBit: UInt32;
+  info: IFixedPointPreCompInfo;
+  lookupTable: IECLookupTable;
+  LK: TCryptoLibUInt32Array;
+begin
+  c := p.curve;
+  size := TFixedPointUtilities.GetCombSize(c);
+  if (k.BitLength > size) then
+  begin
+    // /*
+    // * TODO The comb works best when the scalars are less than the (possibly unknown) order.
+    // * Still, if we want to handle larger scalars, we could allow customization of the comb
+    // * size, or alternatively we could deal with the 'extra' bits either by running the comb
+    // * multiple times as necessary, or by using an alternative multiplier as prelude.
+    // */
+    raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidComputation);
+  end;
+
+  info := TFixedPointUtilities.Precompute(p);
+  lookupTable := info.lookupTable;
+  width := info.width;
+
+  d := (size + width - 1) div width;
+
+  R := c.Infinity;
+  fullComb := d * width;
+  LK := TNat.FromBigInteger(fullComb, k);
+
+  top := fullComb - 1;
+
+  for i := 0 to System.Pred(d) do
+  begin
+
+    secretIndex := 0;
+
+    j := (top - i);
+
+    while j >= 0 do
+    begin
+
+      secretBit := LK[TBits.Asr32(j, 5)] shr (j and $1F);
+      secretIndex := secretIndex xor (secretBit shr 1);
+      secretIndex := secretIndex shl 1;
+      secretIndex := secretIndex xor secretBit;
+
+      System.Dec(j, d);
+    end;
+
+    add := lookupTable.Lookup(Int32(secretIndex));
+    R := R.TwicePlus(add);
+
+  end;
+
+  result := R.add(info.Offset);
+
+end;
+
+{ TGlvMultiplier }
+
+constructor TGlvMultiplier.Create(const curve: IECCurve;
+  const glvEndomorphism: IGlvEndomorphism);
+begin
+  inherited Create();
+  if ((curve = Nil) or (not(curve.Order.IsInitialized))) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SCurveUnknownGroupOrder);
+  end;
+
+  TSetWeakRef.SetWeakReference(@Fcurve, curve);
+  FglvEndomorphism := glvEndomorphism;
+end;
+
+destructor TGlvMultiplier.Destroy;
+begin
+  TSetWeakRef.SetWeakReference(@Fcurve, Nil);
+  inherited Destroy;
+end;
+
+function TGlvMultiplier.MultiplyPositive(const p: IECPoint;
+  const k: TBigInteger): IECPoint;
+var
+  n, a, b: TBigInteger;
+  ab: TCryptoLibGenericArray<TBigInteger>;
+  q: IECPoint;
+begin
+  if (not(Fcurve.Equals(p.curve))) then
+  begin
+    raise EInvalidOperationCryptoLibException.Create('');
+  end;
+
+  n := p.curve.Order;
+  ab := FglvEndomorphism.DecomposeScalar(k.&Mod(n));
+  a := ab[0];
+  b := ab[1];
+
+  if (FglvEndomorphism.HasEfficientPointMap) then
+  begin
+    result := TECAlgorithms.ImplShamirsTrickWNaf(FglvEndomorphism, p, a, b);
+    Exit;
+  end;
+
+  q := TEndoUtilities.MapPoint(FglvEndomorphism, p);
+
+  result := TECAlgorithms.ImplShamirsTrickWNaf(p, a, q, b);
+end;
+
+{ TWNafL2RMultiplier }
+
+constructor TWNafL2RMultiplier.Create;
+begin
+  Inherited Create();
+end;
+
+function TWNafL2RMultiplier.MultiplyPositive(const p: IECPoint;
+  const k: TBigInteger): IECPoint;
+var
+  width, minWidth, i, wi, digit, zeroes, n, highest, scale, lowBits, i1,
+    i2: Int32;
+  info: IWNafPreCompInfo;
+  preComp, preCompNeg, table: TCryptoLibGenericArray<IECPoint>;
+  wnaf: TCryptoLibInt32Array;
+  R, lr: IECPoint;
+begin
+  minWidth := TWNafUtilities.GetWindowSize(k.BitLength);
+
+  info := TWNafUtilities.Precompute(p, minWidth, true);
+  preComp := info.preComp;
+  preCompNeg := info.preCompNeg;
+  width := info.width;
+
+  wnaf := TWNafUtilities.GenerateCompactWindowNaf(width, k);
+
+  R := p.curve.Infinity;
+
+  i := System.Length(wnaf);
+
+  // /*
+  // * NOTE: We try to optimize the first window using the precomputed points to substitute an
+  // * addition for 2 or more doublings.
+  // */
+  if (i > 1) then
+  begin
+    System.Dec(i);
+    wi := wnaf[i];
+    digit := TBits.Asr32(wi, 16);
+    zeroes := wi and $FFFF;
+
+    n := System.Abs(digit);
+    if digit < 0 then
+    begin
+      table := preCompNeg;
+    end
+    else
+    begin
+      table := preComp;
+    end;
+
+    // Optimization can only be used for values in the lower half of the table
+    if ((n shl 2) < (1 shl width)) then
+    begin
+      highest := 32 - TBits.NumberOfLeadingZeros(n);
+
+      // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
+      scale := width - highest;
+      lowBits := n xor (1 shl (highest - 1));
+
+      i1 := ((1 shl (width - 1)) - 1);
+      i2 := (lowBits shl scale) + 1;
+      R := table[TBits.Asr32(i1, 1)].add(table[TBits.Asr32(i2, 1)]);
+
+      zeroes := zeroes - scale;
+    end
+    else
+    begin
+      R := table[TBits.Asr32(n, 1)];
+    end;
+
+    R := R.TimesPow2(zeroes);
+  end;
+
+  while (i > 0) do
+  begin
+    System.Dec(i);
+    wi := wnaf[i];
+    digit := TBits.Asr32(wi, 16);
+    zeroes := wi and $FFFF;
+
+    n := System.Abs(digit);
+    if digit < 0 then
+    begin
+      table := preCompNeg;
+    end
+    else
+    begin
+      table := preComp;
+    end;
+
+    lr := table[TBits.Asr32(n, 1)];
+
+    R := R.TwicePlus(lr);
+    R := R.TimesPow2(zeroes);
+  end;
+
+  result := R;
+
+  info.preComp := Nil; // Review
+  info.preCompNeg := Nil; // Review
+
+end;
+
+{ TWTauNafMultiplier }
+
+constructor TWTauNafMultiplier.Create;
+begin
+  Inherited Create();
+end;
+
+class function TWTauNafMultiplier.MultiplyFromWTnaf(const p: IAbstractF2mPoint;
+  const u: TCryptoLibShortIntArray): IAbstractF2mPoint;
+var
+  curve: IAbstractF2mCurve;
+  a: ShortInt;
+  i, tauCount, ui: Int32;
+  pu, puNeg: TCryptoLibGenericArray<IAbstractF2mPoint>;
+  pre: IWTauNafPreCompInfo;
+  q: IAbstractF2mPoint;
+  x: IECPoint;
+begin
+  curve := p.curve as IAbstractF2mCurve;
+  a := ShortInt(curve.a.ToBigInteger().Int32Value);
+
+  pre := curve.Precompute(p, PRECOMP_NAME, TWTauNafCallback.Create(p, a)
+    as IWTauNafCallback) as IWTauNafPreCompInfo;
+
+  pu := pre.preComp;
+  // TODO Include negations in precomp (optionally) and use from here
+  System.SetLength(puNeg, System.Length(pu));
+  for i := 0 to System.Pred(System.Length(pu)) do
+  begin
+    puNeg[i] := pu[i].Negate() as IAbstractF2mPoint;
+  end;
+
+  q := p.curve.Infinity as IAbstractF2mPoint;
+  tauCount := 0;
+  i := System.Length(u) - 1;
+  while i >= 0 do
+  begin
+    System.Inc(tauCount);
+    ui := u[i];
+    if (ui <> 0) then
+    begin
+      q := q.TauPow(tauCount);
+      tauCount := 0;
+
+      if ui > 0 then
+      begin
+        x := pu[TBits.Asr32(ui, 1)];
+      end
+      else
+      begin
+        x := puNeg[TBits.Asr32(-ui, 1)];
+      end;
+
+      q := q.add(x) as IAbstractF2mPoint;
+    end;
+    System.Dec(i);
+  end;
+  if (tauCount > 0) then
+  begin
+    q := q.TauPow(tauCount);
+  end;
+  result := q;
+
+  pre.preComp := Nil; // Review
+
+end;
+
+function TWTauNafMultiplier.MultiplyWTnaf(const p: IAbstractF2mPoint;
+  const lambda: IZTauElement; a, mu: ShortInt): IAbstractF2mPoint;
+var
+  alpha: TCryptoLibGenericArray<IZTauElement>;
+  tw: TBigInteger;
+  u: TCryptoLibShortIntArray;
+begin
+  if a = 0 then
+  begin
+    alpha := TTnaf.Alpha0;
+  end
+  else
+  begin
+    alpha := TTnaf.Alpha1;
+  end;
+
+  tw := TTnaf.GetTw(mu, TTnaf.width);
+
+  u := TTnaf.TauAdicWNaf(mu, lambda, TTnaf.width,
+    TBigInteger.ValueOf(TTnaf.Pow2Width), tw, alpha);
+
+  result := MultiplyFromWTnaf(p, u);
+end;
+
+function TWTauNafMultiplier.MultiplyPositive(const point: IECPoint;
+  const k: TBigInteger): IECPoint;
+var
+  p: IAbstractF2mPoint;
+  curve: IAbstractF2mCurve;
+  m: Int32;
+  a, mu: ShortInt;
+  s: TCryptoLibGenericArray<TBigInteger>;
+  rho: IZTauElement;
+begin
+  if (not(Supports(point, IAbstractF2mPoint))) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInCompatiblePoint);
+  end;
+
+  p := point as IAbstractF2mPoint;
+  curve := p.curve as IAbstractF2mCurve;
+  m := curve.FieldSize;
+  a := ShortInt(curve.a.ToBigInteger().Int32Value);
+  mu := TTnaf.GetMu(a);
+  s := curve.GetSi();
+
+  rho := TTnaf.PartModReduction(k, m, a, s, mu, ShortInt(10));
+
+  result := MultiplyWTnaf(p, rho, a, mu);
+
+end;
+
+{ TWTauNafMultiplier.TWTauNafCallback }
+
+constructor TWTauNafMultiplier.TWTauNafCallback.Create
+  (const p: IAbstractF2mPoint; a: ShortInt);
+begin
+  Inherited Create();
+  Fm_p := p;
+  Fm_a := a;
+end;
+
+function TWTauNafMultiplier.TWTauNafCallback.Precompute(const existing
+  : IPreCompInfo): IPreCompInfo;
+var
+  tempResult: IWTauNafPreCompInfo;
+begin
+
+  // Review uncomment
+  // if (Supports(existing, IWTauNafPreCompInfo)) then
+  // begin
+  // result := existing;
+  // Exit;
+  // end;
+
+  tempResult := TWTauNafPreCompInfo.Create();
+  tempResult.preComp := TTnaf.GetPreComp(Fm_p, Fm_a);
+  result := tempResult;
+end;
+
+end.

+ 12 - 12
CryptoLib/src/Math/EC/Multiplier/ClpValidityPrecompInfo.pas

@@ -15,7 +15,7 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpValidityPrecompInfo;
+unit ClpValidityPreCompInfo;
 
 {$I ..\..\..\Include\CryptoLib.inc}
 
@@ -23,11 +23,11 @@ interface
 
 uses
   ClpIPreCompInfo,
-  ClpIValidityPrecompInfo;
+  ClpIValidityPreCompInfo;
 
 type
-  TValidityPrecompInfo = class(TInterfacedObject, IPreCompInfo,
-    IValidityPrecompInfo)
+  TValidityPreCompInfo = class(TInterfacedObject, IPreCompInfo,
+    IValidityPreCompInfo)
 
   strict private
 
@@ -52,9 +52,9 @@ type
 
 implementation
 
-{ TValidityPrecompInfo }
+{ TValidityPreCompInfo }
 
-constructor TValidityPrecompInfo.Create;
+constructor TValidityPreCompInfo.Create;
 begin
   Inherited Create();
   Ffailed := False;
@@ -62,32 +62,32 @@ begin
   ForderPassed := False;
 end;
 
-function TValidityPrecompInfo.HasCurveEquationPassed: Boolean;
+function TValidityPreCompInfo.HasCurveEquationPassed: Boolean;
 begin
   result := FcurveEquationPassed;
 end;
 
-function TValidityPrecompInfo.HasFailed: Boolean;
+function TValidityPreCompInfo.HasFailed: Boolean;
 begin
   result := Ffailed;
 end;
 
-function TValidityPrecompInfo.HasOrderPassed: Boolean;
+function TValidityPreCompInfo.HasOrderPassed: Boolean;
 begin
   result := ForderPassed;
 end;
 
-procedure TValidityPrecompInfo.ReportCurveEquationPassed;
+procedure TValidityPreCompInfo.ReportCurveEquationPassed;
 begin
   FcurveEquationPassed := True;
 end;
 
-procedure TValidityPrecompInfo.ReportFailed;
+procedure TValidityPreCompInfo.ReportFailed;
 begin
   Ffailed := True;
 end;
 
-procedure TValidityPrecompInfo.ReportOrderPassed;
+procedure TValidityPreCompInfo.ReportOrderPassed;
 begin
   ForderPassed := True;
 end;

+ 0 - 191
CryptoLib/src/Math/EC/Multiplier/ClpWNafL2RMultiplier.pas

@@ -1,191 +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 ClpWNafL2RMultiplier;
-
-{$I ..\..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  Math,
-  ClpBits,
-  ClpBigInteger,
-  ClpLongArray,
-  ClpCryptoLibTypes,
-  ClpIECC,
-  ClpIWNafPreCompInfo,
-  ClpECAlgorithms,
-  ClpAbstractECMultiplier,
-  ClpIWNafL2RMultiplier;
-
-type
-
-  /// <summary>
-  /// Class implementing the WNAF (Window Non-Adjacent Form) multiplication
-  /// algorithm.
-  /// </summary>
-  TWNafL2RMultiplier = class(TAbstractECMultiplier, IWNafL2RMultiplier)
-
-  strict protected
-    // /**
-    // * Multiplies <code>this</code> by an integer <code>k</code> using the
-    // * Window NAF method.
-    // * @param k The integer by which <code>this</code> is multiplied.
-    // * @return A new <code>ECPoint</code> which equals <code>this</code>
-    // * multiplied by <code>k</code>.
-    // */
-    function MultiplyPositive(const p: IECPoint; const k: TBigInteger)
-      : IECPoint; override;
-
-    /// <summary>
-    /// Determine window width to use for a scalar multiplication of the
-    /// given size.
-    /// </summary>
-    /// <param name="bits">
-    /// the bit-length of the scalar to multiply by
-    /// </param>
-    /// <returns>
-    /// the window size to use
-    /// </returns>
-    function GetWindowSize(bits: Int32): Int32; virtual;
-
-  public
-
-    constructor Create();
-    destructor Destroy; override;
-
-  end;
-
-implementation
-
-{ TWNafL2RMultiplier }
-
-constructor TWNafL2RMultiplier.Create;
-begin
-  Inherited Create();
-end;
-
-destructor TWNafL2RMultiplier.Destroy;
-begin
-  inherited Destroy;
-end;
-
-function TWNafL2RMultiplier.GetWindowSize(bits: Int32): Int32;
-begin
-  Result := TWNafUtilities.GetWindowSize(bits);
-end;
-
-function TWNafL2RMultiplier.MultiplyPositive(const p: IECPoint;
-  const k: TBigInteger): IECPoint;
-var
-  width, i, wi, digit, zeroes, n, highest, scale, lowBits, i1, i2: Int32;
-  wnafPreCompInfo: IWNafPreCompInfo;
-  preComp, preCompNeg, table: TCryptoLibGenericArray<IECPoint>;
-  wnaf: TCryptoLibInt32Array;
-  R, lr: IECPoint;
-begin
-  // Clamp the window width in the range [2, 16]
-  width := Math.Max(2, Math.Min(16, GetWindowSize(k.BitLength)));
-
-  wnafPreCompInfo := TWNafUtilities.Precompute(p, width, true);
-  preComp := wnafPreCompInfo.preComp;
-  preCompNeg := wnafPreCompInfo.preCompNeg;
-
-  wnaf := TWNafUtilities.GenerateCompactWindowNaf(width, k);
-
-  R := p.Curve.Infinity;
-
-  i := System.Length(wnaf);
-
-  // /*
-  // * NOTE: We try to optimize the first window using the precomputed points to substitute an
-  // * addition for 2 or more doublings.
-  // */
-  if (i > 1) then
-  begin
-    System.Dec(i);
-    wi := wnaf[i];
-    digit := TBits.Asr32(wi, 16);
-    zeroes := wi and $FFFF;
-
-    n := System.Abs(digit);
-    if digit < 0 then
-    begin
-      table := preCompNeg;
-    end
-    else
-    begin
-      table := preComp;
-    end;
-
-    // Optimization can only be used for values in the lower half of the table
-    if ((n shl 2) < (1 shl width)) then
-    begin
-      highest := TLongArray.BitLengths[n];
-
-      // TODO Get addition/doubling cost ratio from curve and compare to 'scale' to see if worth substituting?
-      scale := width - highest;
-      lowBits := n xor (1 shl (highest - 1));
-
-      i1 := ((1 shl (width - 1)) - 1);
-      i2 := (lowBits shl scale) + 1;
-      R := table[TBits.Asr32(i1, 1)].Add(table[TBits.Asr32(i2, 1)]);
-
-      zeroes := zeroes - scale;
-
-      // Console.WriteLine("Optimized: 2^" + scale + " * " + n + " = " + i1 + " + " + i2);
-    end
-    else
-    begin
-      R := table[TBits.Asr32(n, 1)];
-    end;
-
-    R := R.TimesPow2(zeroes);
-  end;
-
-  while (i > 0) do
-  begin
-    System.Dec(i);
-    wi := wnaf[i];
-    digit := TBits.Asr32(wi, 16);
-    zeroes := wi and $FFFF;
-
-    n := System.Abs(digit);
-    if digit < 0 then
-    begin
-      table := preCompNeg;
-    end
-    else
-    begin
-      table := preComp;
-    end;
-
-    lr := table[TBits.Asr32(n, 1)];
-
-    R := R.TwicePlus(lr);
-    R := R.TimesPow2(zeroes);
-  end;
-
-  Result := R;
-
-  wnafPreCompInfo.preComp := Nil; // Review
-  wnafPreCompInfo.preCompNeg := Nil; // Review
-
-end;
-
-end.

+ 101 - 22
CryptoLib/src/Math/EC/Multiplier/ClpWNafPreCompInfo.pas

@@ -33,47 +33,72 @@ type
   /// Class holding precomputation data for the WNAF (Window Non-Adjacent
   /// Form) algorithm.
   /// </summary>
-  TWNafPreCompInfo = class(TInterfacedObject, IPreCompInfo, IWNafPreCompInfo)
+  TWNafPreCompInfo = class sealed(TInterfacedObject, IPreCompInfo,
+    IWNafPreCompInfo)
 
   strict private
-    function GetPreComp: TCryptoLibGenericArray<IECPoint>; virtual;
-    procedure SetPreComp(const Value
-      : TCryptoLibGenericArray<IECPoint>); virtual;
-    function GetPreCompNeg: TCryptoLibGenericArray<IECPoint>; virtual;
-    procedure SetPreCompNeg(const Value
-      : TCryptoLibGenericArray<IECPoint>); virtual;
-    function GetTwice: IECPoint; virtual;
-    procedure SetTwice(const Value: IECPoint); virtual;
-  strict protected
   var
     /// <summary>
     /// Array holding the precomputed <c>ECPoint</c>s used for a Window NAF
     /// multiplication.
     /// </summary>
-    Fm_preComp: TCryptoLibGenericArray<IECPoint>;
+    FPreComp: TCryptoLibGenericArray<IECPoint>;
 
     /// <summary>
     /// Array holding the negations of the precomputed <c>ECPoint</c>s used
     /// for a Window NAF multiplication.
     /// </summary>
-    Fm_preCompNeg: TCryptoLibGenericArray<IECPoint>;
+    FPreCompNeg: TCryptoLibGenericArray<IECPoint>;
 
     /// <summary>
     /// Holds an <c>ECPoint</c> representing Twice(this). Used for the Window
     /// NAF multiplication to create or extend the precomputed values.
     /// </summary>
-    Fm_twice: IECPoint;
+    FTwice: IECPoint;
+
+    FConfWidth, FWidth: Int32;
+
+{$IFNDEF FPC}
+{$IFDEF HAS_VOLATILE}[volatile]
+{$ENDIF}
+{$ENDIF}
+    FPromotionCountdown: Int32;
+
+    function GetPreComp: TCryptoLibGenericArray<IECPoint>; inline;
+    procedure SetPreComp(const Value: TCryptoLibGenericArray<IECPoint>); inline;
+    function GetPreCompNeg: TCryptoLibGenericArray<IECPoint>; inline;
+    procedure SetPreCompNeg(const Value
+      : TCryptoLibGenericArray<IECPoint>); inline;
+    function GetTwice: IECPoint; inline;
+    procedure SetTwice(const Value: IECPoint); inline;
+
+    function GetConfWidth: Int32; inline;
+    procedure SetConfWidth(Value: Int32); inline;
+
+    function GetWidth: Int32; inline;
+    procedure SetWidth(Value: Int32); inline;
+
+    function GetPromotionCountdown: Int32; inline;
+    procedure SetPromotionCountdown(Value: Int32); inline;
+
+    function DecrementPromotionCountdown: Int32; inline;
+    function IsPromoted: Boolean; inline;
 
   public
 
     constructor Create();
-    destructor Destroy; override;
     property PreComp: TCryptoLibGenericArray<IECPoint> read GetPreComp
       write SetPreComp;
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
       write SetPreCompNeg;
     property Twice: IECPoint read GetTwice write SetTwice;
 
+    property ConfWidth: Int32 read GetConfWidth write SetConfWidth;
+    property Width: Int32 read GetWidth write SetWidth;
+
+    property PromotionCountdown: Int32 read GetPromotionCountdown
+      write SetPromotionCountdown;
+
   end;
 
 implementation
@@ -83,43 +108,97 @@ implementation
 constructor TWNafPreCompInfo.Create;
 begin
   inherited Create();
+  FConfWidth := -1;
+  FWidth := -1;
+  FPromotionCountdown := 4;
+end;
+
+function TWNafPreCompInfo.DecrementPromotionCountdown: Int32;
+var
+  t: Int32;
+begin
+  t := PromotionCountdown;
+  if (t > 0) then
+  begin
+    System.Dec(t);
+    PromotionCountdown := t;
+  end;
+  result := t;
 end;
 
-destructor TWNafPreCompInfo.Destroy;
+function TWNafPreCompInfo.GetConfWidth: Int32;
 begin
-  inherited Destroy;
+  result := FConfWidth;
 end;
 
 function TWNafPreCompInfo.GetPreComp: TCryptoLibGenericArray<IECPoint>;
 begin
-  Result := Fm_preComp;
+  result := FPreComp;
 end;
 
 function TWNafPreCompInfo.GetPreCompNeg: TCryptoLibGenericArray<IECPoint>;
 begin
-  Result := Fm_preCompNeg;
+  result := FPreCompNeg;
+end;
+
+function TWNafPreCompInfo.GetPromotionCountdown: Int32;
+begin
+{$IFDEF FPC}
+  result := {$IFDEF HAS_VOLATILE}volatile{$ENDIF}(FPromotionCountdown);
+{$ELSE}
+    result := FPromotionCountdown;
+{$ENDIF}
 end;
 
 function TWNafPreCompInfo.GetTwice: IECPoint;
 begin
-  Result := Fm_twice;
+  result := FTwice;
+end;
+
+function TWNafPreCompInfo.GetWidth: Int32;
+begin
+  result := FWidth;
+end;
+
+function TWNafPreCompInfo.IsPromoted: Boolean;
+begin
+  result := PromotionCountdown <= 0;
+end;
+
+procedure TWNafPreCompInfo.SetConfWidth(Value: Int32);
+begin
+  FConfWidth := Value;
 end;
 
 procedure TWNafPreCompInfo.SetPreComp(const Value
   : TCryptoLibGenericArray<IECPoint>);
 begin
-  Fm_preComp := Value;
+  FPreComp := Value;
 end;
 
 procedure TWNafPreCompInfo.SetPreCompNeg(const Value
   : TCryptoLibGenericArray<IECPoint>);
 begin
-  Fm_preCompNeg := Value;
+  FPreCompNeg := Value;
+end;
+
+procedure TWNafPreCompInfo.SetPromotionCountdown(Value: Int32);
+begin
+{$IFDEF FPC}
+  FPromotionCountdown := {$IFDEF HAS_VOLATILE}volatile{$ENDIF}(Value);
+{$ELSE}
+    FPromotionCountdown := Value;
+{$ENDIF}
 end;
 
 procedure TWNafPreCompInfo.SetTwice(const Value: IECPoint);
 begin
-  Fm_twice := Value;
+  FTwice := Value;
+end;
+
+procedure TWNafPreCompInfo.SetWidth(Value: Int32);
+begin
+  FWidth := Value;
 end;
 
 end.

+ 0 - 276
CryptoLib/src/Math/EC/Multiplier/ClpWTauNafMultiplier.pas

@@ -1,276 +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 ClpWTauNafMultiplier;
-
-{$I ..\..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  SysUtils,
-  ClpBits,
-  ClpBigInteger,
-  ClpCryptoLibTypes,
-  ClpTNaf,
-  ClpAbstractECMultiplier,
-  ClpIWTauNafPreCompInfo,
-  ClpWTauNafPreCompInfo,
-  ClpIECC,
-  ClpIPreCompCallBack,
-  ClpIZTauElement,
-  ClpIPreCompInfo,
-  ClpIWTauNafMultiplier;
-
-resourcestring
-  SInCompatiblePoint = 'Only AbstractF2mPoint can be used in WTauNafMultiplier';
-
-type
-  /// **
-  // * Class implementing the WTNAF (Window
-  // * <code>&#964;</code>-adic Non-Adjacent Form) algorithm.
-  // */
-  TWTauNafMultiplier = class(TAbstractECMultiplier, IWTauNafMultiplier)
-
-  strict private
-    // TODO Create WTauNafUtilities class and move various functionality into it
-
-  type
-    IWTauNafCallback = interface(IPreCompCallback)
-      ['{4D6F7B4A-B925-42C9-8D60-B7F24632EDC1}']
-
-    end;
-
-  type
-    TWTauNafCallback = class(TInterfacedObject, IPreCompCallback,
-      IWTauNafCallback)
-
-    strict private
-    var
-      Fm_p: IAbstractF2mPoint;
-      Fm_a: ShortInt;
-
-    public
-      constructor Create(const p: IAbstractF2mPoint; a: ShortInt);
-
-      function Precompute(const existing: IPreCompInfo): IPreCompInfo;
-
-    end;
-
-  const
-    PRECOMP_NAME: String = 'bc_wtnaf';
-
-    // /**
-    // * Multiplies an AbstractF2mPoint
-    // * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code> using
-    // * the <code>&#964;</code>-adic NAF (TNAF) method.
-    // * @param p The AbstractF2mPoint to multiply.
-    // * @param lambda The element <code>&#955;</code> of
-    // * <code><b>Z</b>[&#964;]</code> of which to compute the
-    // * <code>[&#964;]</code>-adic NAF.
-    // * @return <code>p</code> multiplied by <code>&#955;</code>.
-    // */
-    function MultiplyWTnaf(const p: IAbstractF2mPoint;
-      const lambda: IZTauElement; a, mu: ShortInt): IAbstractF2mPoint; inline;
-
-    // /**
-    // * Multiplies an AbstractF2mPoint
-    // * by an element <code>&#955;</code> of <code><b>Z</b>[&#964;]</code>
-    // * using the window <code>&#964;</code>-adic NAF (TNAF) method, given the
-    // * WTNAF of <code>&#955;</code>.
-    // * @param p The AbstractF2mPoint to multiply.
-    // * @param u The the WTNAF of <code>&#955;</code>..
-    // * @return <code>&#955; * p</code>
-    // */
-    class function MultiplyFromWTnaf(const p: IAbstractF2mPoint;
-      const u: TCryptoLibShortIntArray): IAbstractF2mPoint; static;
-
-  strict protected
-    // /**
-    // * Multiplies an AbstractF2mPoint
-    // * by <code>k</code> using the reduced <code>&#964;</code>-adic NAF (RTNAF)
-    // * method.
-    // * @param p The AbstractF2mPoint to multiply.
-    // * @param k The integer by which to multiply <code>k</code>.
-    // * @return <code>p</code> multiplied by <code>k</code>.
-    // */
-    function MultiplyPositive(const point: IECPoint; const k: TBigInteger)
-      : IECPoint; override;
-
-  public
-    constructor Create();
-    destructor Destroy; override;
-
-  end;
-
-implementation
-
-{ TWTauNafMultiplier }
-
-constructor TWTauNafMultiplier.Create;
-begin
-  Inherited Create();
-end;
-
-destructor TWTauNafMultiplier.Destroy;
-begin
-  inherited Destroy;
-end;
-
-class function TWTauNafMultiplier.MultiplyFromWTnaf(const p: IAbstractF2mPoint;
-  const u: TCryptoLibShortIntArray): IAbstractF2mPoint;
-var
-  curve: IAbstractF2mCurve;
-  a: ShortInt;
-  i, tauCount, ui: Int32;
-  pu, puNeg: TCryptoLibGenericArray<IAbstractF2mPoint>;
-  pre: IWTauNafPreCompInfo;
-  q: IAbstractF2mPoint;
-  x: IECPoint;
-  callback: IWTauNafCallback;
-begin
-  curve := p.curve as IAbstractF2mCurve;
-  a := ShortInt(curve.a.ToBigInteger().Int32Value);
-
-  callback := TWTauNafCallback.Create(p, a);
-  pre := curve.Precompute(p, PRECOMP_NAME, callback) as IWTauNafPreCompInfo;
-
-  pu := pre.PreComp;
-  // TODO Include negations in precomp (optionally) and use from here
-  System.SetLength(puNeg, System.Length(pu));
-  for i := 0 to System.Pred(System.Length(pu)) do
-  begin
-    puNeg[i] := pu[i].Negate() as IAbstractF2mPoint;
-  end;
-
-  // q = infinity
-  q := p.curve.Infinity as IAbstractF2mPoint;
-  tauCount := 0;
-  i := System.Length(u) - 1;
-  while i >= 0 do
-  begin
-    System.Inc(tauCount);
-    ui := u[i];
-    if (ui <> 0) then
-    begin
-      q := q.TauPow(tauCount);
-      tauCount := 0;
-
-      if ui > 0 then
-      begin
-        x := pu[TBits.Asr32(ui, 1)];
-      end
-      else
-      begin
-        x := puNeg[TBits.Asr32(-ui, 1)];
-      end;
-
-      q := q.Add(x) as IAbstractF2mPoint;
-    end;
-    System.Dec(i);
-  end;
-  if (tauCount > 0) then
-  begin
-    q := q.TauPow(tauCount);
-  end;
-  result := q;
-
-  pre.PreComp := Nil; // Review
-
-end;
-
-function TWTauNafMultiplier.MultiplyWTnaf(const p: IAbstractF2mPoint;
-  const lambda: IZTauElement; a, mu: ShortInt): IAbstractF2mPoint;
-var
-  alpha: TCryptoLibGenericArray<IZTauElement>;
-  tw: TBigInteger;
-  u: TCryptoLibShortIntArray;
-begin
-  if a = 0 then
-  begin
-    alpha := TTnaf.Alpha0;
-  end
-  else
-  begin
-    alpha := TTnaf.Alpha1;
-  end;
-
-  tw := TTnaf.GetTw(mu, TTnaf.Width);
-
-  u := TTnaf.TauAdicWNaf(mu, lambda, TTnaf.Width,
-    TBigInteger.ValueOf(TTnaf.Pow2Width), tw, alpha);
-
-  result := MultiplyFromWTnaf(p, u);
-end;
-
-function TWTauNafMultiplier.MultiplyPositive(const point: IECPoint;
-  const k: TBigInteger): IECPoint;
-var
-  p: IAbstractF2mPoint;
-  curve: IAbstractF2mCurve;
-  m: Int32;
-  a, mu: ShortInt;
-  s: TCryptoLibGenericArray<TBigInteger>;
-  rho: IZTauElement;
-begin
-  if (not(Supports(point, IAbstractF2mPoint))) then
-  begin
-    raise EArgumentCryptoLibException.CreateRes(@SInCompatiblePoint);
-  end;
-
-  p := point as IAbstractF2mPoint;
-  curve := p.curve as IAbstractF2mCurve;
-  m := curve.FieldSize;
-  a := ShortInt(curve.a.ToBigInteger().Int32Value);
-  mu := TTnaf.GetMu(a);
-  s := curve.GetSi();
-
-  rho := TTnaf.PartModReduction(k, m, a, s, mu, ShortInt(10));
-
-  result := MultiplyWTnaf(p, rho, a, mu);
-
-end;
-
-{ TWTauNafMultiplier.TWTauNafCallback }
-
-constructor TWTauNafMultiplier.TWTauNafCallback.Create
-  (const p: IAbstractF2mPoint; a: ShortInt);
-begin
-  Inherited Create();
-  Fm_p := p;
-  Fm_a := a;
-end;
-
-function TWTauNafMultiplier.TWTauNafCallback.Precompute(const existing
-  : IPreCompInfo): IPreCompInfo;
-var
-  tempResult: IWTauNafPreCompInfo;
-begin
-
-  // Review uncomment
-  // if (Supports(existing, IWTauNafPreCompInfo)) then
-  // begin
-  // result := existing;
-  // Exit;
-  // end;
-
-  tempResult := TWTauNafPreCompInfo.Create();
-  tempResult.PreComp := TTnaf.GetPreComp(Fm_p, Fm_a);
-  result := tempResult;
-end;
-
-end.

+ 23 - 23
CryptoLib/src/Math/EC/Rfc8032/ClpEd25519.pas

@@ -291,9 +291,6 @@ type
     class procedure PruneScalar(const n: TCryptoLibByteArray; nOff: Int32;
       const r: TCryptoLibByteArray); static; inline;
 
-    class procedure ScalarMult(const k: TCryptoLibByteArray;
-      var p: TPointAffine; var r: TPointAccum); static;
-
     class function ReduceScalar(const n: TCryptoLibByteArray)
       : TCryptoLibByteArray; static;
 
@@ -303,7 +300,7 @@ type
     class procedure ScalarMultBaseEncoded(const k, r: TCryptoLibByteArray;
       rOff: Int32); static; inline;
 
-    class procedure ScalarMultStraussVar(const nb, np: TCryptoLibUInt32Array;
+    class procedure ScalarMultStrausVar(const nb, np: TCryptoLibUInt32Array;
       var p: TPointAffine; var r: TPointAccum); static;
 
     class function ValidateDigestOutputSize(const ADigest: IDigest)
@@ -345,6 +342,7 @@ type
 
   class procedure Precompute(); static;
 
+  // NOTE: Only for use by X25519
   class procedure ScalarMultBaseYZ(const k: TCryptoLibByteArray; kOff: Int32;
     const Y, Z: TCryptoLibInt32Array); static; inline;
 
@@ -398,6 +396,9 @@ type
     const pk: TCryptoLibByteArray; pkOff: Int32; const ctx: TCryptoLibByteArray;
     const ph: IDigest): Boolean; overload;
 
+  class procedure ScalarMult(const k: TCryptoLibByteArray; var p: TPointAffine;
+    var r: TPointAccum); static;
+
   end;
 
 implementation
@@ -765,18 +766,28 @@ begin
   TX25519Field.Copy(table, off, r.T, 0);
 end;
 
+class function TEd25519.GetWindow4(const X: TCryptoLibUInt32Array;
+  n: Int32): Int32;
+var
+  w, b: Int32;
+begin
+  w := TBits.Asr32(n, 3);
+  b := (n and 7) shl 2;
+  result := (X[w] shr b) and 15;
+end;
+
 class procedure TEd25519.PointLookup(const X: TCryptoLibUInt32Array; n: Int32;
   const table: TCryptoLibInt32Array; var r: TPointExt);
 var
-  w, Sign, abs, i, off, cond: Int32;
+  w, LSign, abs, i, off, cond: Int32;
 begin
   w := GetWindow4(X, n);
 
-  Sign := (TBits.Asr32(w, (PrecompTeeth - 1))) xor 1;
-  abs := (w xor -Sign) and PrecompMask;
+  LSign := (TBits.Asr32(w, (PrecompTeeth - 1))) xor 1;
+  abs := (w xor -LSign) and PrecompMask;
 
 {$IFDEF DEBUG}
-  System.Assert((Sign = 0) or (Sign = 1));
+  System.Assert((LSign = 0) or (LSign = 1));
   System.Assert((abs <= 0) and (abs < PrecompPoints));
 {$ENDIF DEBUG}
   i := 0;
@@ -796,8 +807,8 @@ begin
     System.Inc(i);
   end;
 
-  TX25519Field.CNegate(Sign, r.X);
-  TX25519Field.CNegate(Sign, r.T);
+  TX25519Field.CNegate(LSign, r.X);
+  TX25519Field.CNegate(LSign, r.T);
 end;
 
 class function TEd25519.DecodePointVar(const p: TCryptoLibByteArray;
@@ -932,17 +943,6 @@ begin
   ScalarMultBaseEncoded(s, pk, pkOff);
 end;
 
-class function TEd25519.GetWindow4(const X: TCryptoLibUInt32Array;
-  n: Int32): Int32;
-var
-  w, b: Int32;
-begin
-  w := TBits.Asr32(n, 3);
-  b := (n and 7) shl 2;
-  result := (X[w] shr b) and 15;
-  // result := (TBits.Asr32(X[w], b)) and 15;
-end;
-
 class function TEd25519.GetWnaf(const n: TCryptoLibUInt32Array; width: Int32)
   : TCryptoLibShortIntArray;
 var
@@ -1156,7 +1156,7 @@ begin
   DecodeScalar(k, 0, nA);
 
   pR := TPointAccum.CreatePointAccum();
-  ScalarMultStraussVar(nS, nA, pA, pR);
+  ScalarMultStrausVar(nS, nA, pA, pR);
 
   System.SetLength(check, PointBytes);
 
@@ -1935,7 +1935,7 @@ begin
   TX25519Field.Copy(p.Z, 0, Z, 0);
 end;
 
-class procedure TEd25519.ScalarMultStraussVar(const nb,
+class procedure TEd25519.ScalarMultStrausVar(const nb,
   np: TCryptoLibUInt32Array; var p: TPointAffine; var r: TPointAccum);
 var
   width, bit, wb, wp, LSign, index: Int32;

+ 59 - 3
CryptoLib/src/Math/Raw/ClpNat.pas

@@ -118,6 +118,16 @@ type
       xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32); overload;
       static; inline;
 
+    class procedure Copy64(len: Int32; const x, z: TCryptoLibUInt64Array);
+      overload; static; inline;
+
+    class function Copy64(len: Int32; const x: TCryptoLibUInt64Array)
+      : TCryptoLibUInt64Array; overload; static; inline;
+
+    class procedure Copy64(len: Int32; const x: TCryptoLibUInt64Array;
+      xOff: Int32; const z: TCryptoLibUInt64Array; zOff: Int32); overload;
+      static; inline;
+
     class function Create(len: Int32): TCryptoLibUInt32Array; static; inline;
 
     class function Create64(len: Int32): TCryptoLibUInt64Array; static; inline;
@@ -151,6 +161,9 @@ type
     class function FromBigInteger(bits: Int32; const x: TBigInteger)
       : TCryptoLibUInt32Array; static;
 
+    class function FromBigInteger64(bits: Int32; const x: TBigInteger)
+      : TCryptoLibUInt64Array; static;
+
     class function GetBit(const x: TCryptoLibUInt32Array; bit: Int32)
       : UInt32; static;
 
@@ -961,7 +974,7 @@ end;
 class procedure TNat.CMov(len, mask: Int32; const x: TCryptoLibUInt32Array;
   xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32);
 var
-  LMASK, z_i, Diff: UInt32;
+  LMASK, z_i, LDiff: UInt32;
   I: Int32;
 begin
   LMASK := UInt32(-(mask and 1));
@@ -969,8 +982,8 @@ begin
   for I := 0 to System.Pred(len) do
   begin
     z_i := z[zOff + I];
-    Diff := z_i xor x[xOff + I];
-    z_i := z_i xor ((Diff and LMASK));
+    LDiff := z_i xor x[xOff + I];
+    z_i := z_i xor ((LDiff and LMASK));
     z[zOff + I] := z_i;
   end;
 end;
@@ -987,6 +1000,24 @@ begin
   System.Move(x[0], z[0], len * System.SizeOf(UInt32));
 end;
 
+class procedure TNat.Copy64(len: Int32; const x: TCryptoLibUInt64Array;
+  xOff: Int32; const z: TCryptoLibUInt64Array; zOff: Int32);
+begin
+  System.Move(x[xOff], z[zOff], len * System.SizeOf(UInt64));
+end;
+
+class function TNat.Copy64(len: Int32; const x: TCryptoLibUInt64Array)
+  : TCryptoLibUInt64Array;
+begin
+  System.SetLength(Result, len);
+  System.Move(x[0], Result[0], len * System.SizeOf(UInt64));
+end;
+
+class procedure TNat.Copy64(len: Int32; const x, z: TCryptoLibUInt64Array);
+begin
+  System.Move(x[0], z[0], len * System.SizeOf(UInt64));
+end;
+
 class procedure TNat.Copy(len: Int32; const x: TCryptoLibUInt32Array;
   xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32);
 begin
@@ -1180,6 +1211,31 @@ begin
   end;
 end;
 
+class function TNat.FromBigInteger64(bits: Int32; const x: TBigInteger)
+  : TCryptoLibUInt64Array;
+var
+  len, I: Int32;
+  z: TCryptoLibUInt64Array;
+  Lx: TBigInteger;
+begin
+  Lx := x;
+  if ((Lx.SignValue < 0) or (Lx.BitLength > bits)) then
+  begin
+    raise EArgumentCryptoLibException.Create('');
+  end;
+
+  len := (bits + 63) shr 6;
+  z := Create64(len);
+  I := 0;
+  while (Lx.SignValue <> 0) do
+  begin
+    z[I] := Lx.Int64Value;
+    System.Inc(I);
+    Lx := Lx.ShiftRight(64);
+  end;
+  Result := z;
+end;
+
 class function TNat.GetBit(const x: TCryptoLibUInt32Array; bit: Int32): UInt32;
 var
   w, b: Int32;

+ 19 - 14
CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk

@@ -232,7 +232,7 @@ contains
   ClpIHMacDsaKCalculator in '..\..\Interfaces\ClpIHMacDsaKCalculator.pas',
   ClpInterleave in '..\..\Math\Raw\ClpInterleave.pas',
   ClpIPreCompCallBack in '..\..\Interfaces\ClpIPreCompCallBack.pas',
-  ClpIValidityPrecompInfo in '..\..\Interfaces\ClpIValidityPrecompInfo.pas',
+  ClpIValidityPreCompInfo in '..\..\Interfaces\ClpIValidityPreCompInfo.pas',
   ClpNat192 in '..\..\Math\Raw\ClpNat192.pas',
   ClpNat256 in '..\..\Math\Raw\ClpNat256.pas',
   ClpNat320 in '..\..\Math\Raw\ClpNat320.pas',
@@ -283,7 +283,6 @@ contains
   ClpECDHBasicAgreement in '..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas',
   ClpGenericPolynomialExtensionField in '..\..\Math\Field\ClpGenericPolynomialExtensionField.pas',
   ClpGF2Polynomial in '..\..\Math\Field\ClpGF2Polynomial.pas',
-  ClpGlvMultiplier in '..\..\Math\EC\Multiplier\ClpGlvMultiplier.pas',
   ClpIAesEngine in '..\..\Interfaces\ClpIAesEngine.pas',
   ClpIBlockCipher in '..\..\Interfaces\ClpIBlockCipher.pas',
   ClpIBlockCipherPadding in '..\..\Interfaces\ClpIBlockCipherPadding.pas',
@@ -293,13 +292,10 @@ contains
   ClpIDsaDigestSigner in '..\..\Interfaces\ClpIDsaDigestSigner.pas',
   ClpIGenericPolynomialExtensionField in '..\..\Interfaces\ClpIGenericPolynomialExtensionField.pas',
   ClpIGF2Polynomial in '..\..\Interfaces\ClpIGF2Polynomial.pas',
-  ClpIGlvMultiplier in '..\..\Interfaces\ClpIGlvMultiplier.pas',
   ClpIKeyParameter in '..\..\Interfaces\ClpIKeyParameter.pas',
   ClpIPaddedBufferedBlockCipher in '..\..\Interfaces\ClpIPaddedBufferedBlockCipher.pas',
   ClpIParametersWithIV in '..\..\Interfaces\ClpIParametersWithIV.pas',
   ClpIPrimeField in '..\..\Interfaces\ClpIPrimeField.pas',
-  ClpIWNafL2RMultiplier in '..\..\Interfaces\ClpIWNafL2RMultiplier.pas',
-  ClpIWTauNafMultiplier in '..\..\Interfaces\ClpIWTauNafMultiplier.pas',
   ClpIWTauNafPreCompInfo in '..\..\Interfaces\ClpIWTauNafPreCompInfo.pas',
   ClpIZTauElement in '..\..\Interfaces\ClpIZTauElement.pas',
   ClpKeyParameter in '..\..\Crypto\Parameters\ClpKeyParameter.pas',
@@ -307,23 +303,17 @@ contains
   ClpParametersWithIV in '..\..\Crypto\Parameters\ClpParametersWithIV.pas',
   ClpPrimeField in '..\..\Math\Field\ClpPrimeField.pas',
   ClpSetWeakRef in '..\..\Utils\ClpSetWeakRef.pas',
-  ClpWNafL2RMultiplier in '..\..\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas',
-  ClpWTauNafMultiplier in '..\..\Math\EC\Multiplier\ClpWTauNafMultiplier.pas',
   ClpWTauNafPreCompInfo in '..\..\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpZTauElement in '..\..\Math\EC\Abc\ClpZTauElement.pas',
-  ClpAbstractECMultiplier in '..\..\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
   ClpArrayUtils in '..\..\Utils\ClpArrayUtils.pas',
   ClpBigIntegers in '..\..\Utils\ClpBigIntegers.pas',
-  ClpFixedPointCombMultiplier in '..\..\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
   ClpFixedPointPreCompInfo in '..\..\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
-  ClpFixedPointUtilities in '..\..\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
   ClpGlvTypeBEndomorphism in '..\..\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\Math\EC\Endo\ClpGlvTypeBParameters.pas',
   ClpIDsa in '..\..\Interfaces\ClpIDsa.pas',
   ClpIDsaKCalculator in '..\..\Interfaces\ClpIDsaKCalculator.pas',
   ClpIECDsaSigner in '..\..\Interfaces\ClpIECDsaSigner.pas',
   ClpIFiniteField in '..\..\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -349,7 +339,6 @@ contains
   ClpTimes in '..\..\Utils\ClpTimes.pas',
   ClpWNafPreCompInfo in '..\..\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpAsymmetricCipherKeyPair in '..\..\Crypto\ClpAsymmetricCipherKeyPair.pas',
-  ClpIAbstractECMultiplier in '..\..\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -360,7 +349,7 @@ contains
   ClpIECKeyPairGenerator in '..\..\Interfaces\ClpIECKeyPairGenerator.pas',
   ClpIExtensionField in '..\..\Interfaces\ClpIExtensionField.pas',
   ClpOidTokenizer in '..\..\Asn1\ClpOidTokenizer.pas',
-  ClpValidityPrecompInfo in '..\..\Math\EC\Multiplier\ClpValidityPrecompInfo.pas',
+  ClpValidityPreCompInfo in '..\..\Math\EC\Multiplier\ClpValidityPreCompInfo.pas',
   ClpTeleTrusTNamedCurves in '..\..\Asn1\TeleTrust\ClpTeleTrusTNamedCurves.pas',
   ClpAgreementUtilities in '..\..\Security\ClpAgreementUtilities.pas',
   ClpIKdf1BytesGenerator in '..\..\Interfaces\ClpIKdf1BytesGenerator.pas',
@@ -402,6 +391,22 @@ contains
   ClpIDHValidationParameters in '..\..\Interfaces\ClpIDHValidationParameters.pas',
   ClpIDHDomainParameters in '..\..\Interfaces\ClpIDHDomainParameters.pas',
   ClpIDHValidationParams in '..\..\Interfaces\ClpIDHValidationParams.pas',
-  ClpAESPRNGRandom in '..\..\Utils\Randoms\ClpAESPRNGRandom.pas';
+  ClpAESPRNGRandom in '..\..\Utils\Randoms\ClpAESPRNGRandom.pas',
+  ClpCryptLibObjectIdentifiers in '..\..\Asn1\CryptLib\ClpCryptLibObjectIdentifiers.pas',
+  ClpIGlvTypeAParameters in '..\..\Interfaces\ClpIGlvTypeAParameters.pas',
+  ClpIGlvTypeAEndomorphism in '..\..\Interfaces\ClpIGlvTypeAEndomorphism.pas',
+  ClpIScaleXNegateYPointMap in '..\..\Interfaces\ClpIScaleXNegateYPointMap.pas',
+  ClpIScaleYNegateXPointMap in '..\..\Interfaces\ClpIScaleYNegateXPointMap.pas',
+  ClpIScalarSplitParameters in '..\..\Interfaces\ClpIScalarSplitParameters.pas',
+  ClpIEndoPreCompInfo in '..\..\Interfaces\ClpIEndoPreCompInfo.pas',
+  ClpScaleXNegateYPointMap in '..\..\Math\EC\ClpScaleXNegateYPointMap.pas',
+  ClpScaleYNegateXPointMap in '..\..\Math\EC\ClpScaleYNegateXPointMap.pas',
+  ClpEndoPreCompInfo in '..\..\Math\EC\Endo\ClpEndoPreCompInfo.pas',
+  ClpGlvTypeAEndomorphism in '..\..\Math\EC\Endo\ClpGlvTypeAEndomorphism.pas',
+  ClpGlvTypeAParameters in '..\..\Math\EC\Endo\ClpGlvTypeAParameters.pas',
+  ClpScalarSplitParameters in '..\..\Math\EC\Endo\ClpScalarSplitParameters.pas',
+  ClpMultipliers in '..\..\Math\EC\Multiplier\ClpMultipliers.pas',
+  ClpIMultipliers in '..\..\Interfaces\ClpIMultipliers.pas',
+  ClpECCompUtilities in '..\..\Math\EC\ClpECCompUtilities.pas';
 
 end.

+ 693 - 682
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk

@@ -10,7 +10,7 @@
       <PathDelim Value="\"/>
       <SearchPaths>
         <IncludeFiles Value="..\..\Include"/>
-        <OtherUnitFiles Value="..\..\Asn1;..\..\Asn1\CryptoPro;..\..\Asn1\Nist;..\..\Asn1\Oiw;..\..\Asn1\Pkcs;..\..\Asn1\RossStandart;..\..\Asn1\Sec;..\..\Asn1\TeleTrust;..\..\Asn1\X9;..\..\Crypto;..\..\Crypto\Generators;..\..\Crypto\Parameters;..\..\Crypto\Prng;..\..\Crypto\Signers;..\..\Interfaces;..\..\Math;..\..\Math\EC;..\..\Math\EC\Abc;..\..\Math\EC\Endo;..\..\Math\EC\Multiplier;..\..\Math\Field;..\..\Math\Raw;..\..\Security;..\..\Utils;..\..\Utils\Encoders;..\..\Utils\Randoms;..\..\Utils\Rng;..\..\Crypto\Modes;..\..\Crypto\Paddings;..\..\Crypto\Engines;..\..\Crypto\Parsers;..\..\Crypto\Agreement;..\..\Crypto\Macs;..\..\Asn1\Misc;..\..\Asn1\Iana;..\..\Crypto\Digests;..\..\Asn1\X509;..\..\Crypto\EC;..\..\Math\EC\Custom\Sec;..\..\Asn1\Bsi;..\..\Asn1\Eac;..\..\Crypto\Signers\SignersEncodings;..\..\Math\EC\Custom\Djb;..\..\Math\EC\Rfc7748;..\..\Math\EC\Rfc8032;..\..\Asn1\Edec"/>
+        <OtherUnitFiles Value="..\..\Asn1;..\..\Asn1\CryptoPro;..\..\Asn1\Nist;..\..\Asn1\Oiw;..\..\Asn1\Pkcs;..\..\Asn1\RossStandart;..\..\Asn1\Sec;..\..\Asn1\TeleTrust;..\..\Asn1\X9;..\..\Crypto;..\..\Crypto\Generators;..\..\Crypto\Parameters;..\..\Crypto\Prng;..\..\Crypto\Signers;..\..\Interfaces;..\..\Math;..\..\Math\EC;..\..\Math\EC\Abc;..\..\Math\EC\Endo;..\..\Math\EC\Multiplier;..\..\Math\Field;..\..\Math\Raw;..\..\Security;..\..\Utils;..\..\Utils\Encoders;..\..\Utils\Randoms;..\..\Utils\Rng;..\..\Crypto\Modes;..\..\Crypto\Paddings;..\..\Crypto\Engines;..\..\Crypto\Parsers;..\..\Crypto\Agreement;..\..\Crypto\Macs;..\..\Asn1\Misc;..\..\Asn1\Iana;..\..\Crypto\Digests;..\..\Asn1\X509;..\..\Crypto\EC;..\..\Math\EC\Custom\Sec;..\..\Asn1\Bsi;..\..\Asn1\Eac;..\..\Crypto\Signers\SignersEncodings;..\..\Math\EC\Custom\Djb;..\..\Math\EC\Rfc7748;..\..\Math\EC\Rfc8032;..\..\Asn1\Edec;..\..\Asn1\CryptLib"/>
         <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
       </SearchPaths>
       <CodeGeneration>
@@ -25,7 +25,7 @@
  Acknowledgements: 
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
     <Version Major="3" Minor="1"/>
-    <Files Count="370">
+    <Files Count="373">
       <Item1>
         <Filename Value="..\..\Asn1\ClpOidTokenizer.pas"/>
         <UnitName Value="ClpOidTokenizer"/>
@@ -151,1363 +151,1374 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <Type Value="Include"/>
       </Item31>
       <Item32>
-        <Filename Value="..\..\Interfaces\ClpIAbstractECMultiplier.pas"/>
-        <UnitName Value="ClpIAbstractECMultiplier"/>
-      </Item32>
-      <Item33>
         <Filename Value="..\..\Interfaces\ClpIAsymmetricCipherKeyPair.pas"/>
         <UnitName Value="ClpIAsymmetricCipherKeyPair"/>
-      </Item33>
-      <Item34>
+      </Item32>
+      <Item33>
         <Filename Value="..\..\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas"/>
         <UnitName Value="ClpIAsymmetricCipherKeyPairGenerator"/>
-      </Item34>
-      <Item35>
+      </Item33>
+      <Item34>
         <Filename Value="..\..\Interfaces\ClpIAsymmetricKeyParameter.pas"/>
         <UnitName Value="ClpIAsymmetricKeyParameter"/>
-      </Item35>
-      <Item36>
+      </Item34>
+      <Item35>
         <Filename Value="..\..\Interfaces\ClpICipherParameters.pas"/>
         <UnitName Value="ClpICipherParameters"/>
-      </Item36>
-      <Item37>
+      </Item35>
+      <Item36>
         <Filename Value="..\..\Interfaces\ClpICryptoApiRandomGenerator.pas"/>
         <UnitName Value="ClpICryptoApiRandomGenerator"/>
-      </Item37>
-      <Item38>
+      </Item36>
+      <Item37>
         <Filename Value="..\..\Interfaces\ClpIDigestRandomGenerator.pas"/>
         <UnitName Value="ClpIDigestRandomGenerator"/>
-      </Item38>
-      <Item39>
+      </Item37>
+      <Item38>
         <Filename Value="..\..\Interfaces\ClpIDsa.pas"/>
         <UnitName Value="ClpIDsa"/>
-      </Item39>
-      <Item40>
+      </Item38>
+      <Item39>
         <Filename Value="..\..\Interfaces\ClpIDsaDigestSigner.pas"/>
         <UnitName Value="ClpIDsaDigestSigner"/>
-      </Item40>
-      <Item41>
+      </Item39>
+      <Item40>
         <Filename Value="..\..\Interfaces\ClpIDsaKCalculator.pas"/>
         <UnitName Value="ClpIDsaKCalculator"/>
-      </Item41>
-      <Item42>
+      </Item40>
+      <Item41>
         <Filename Value="..\..\Interfaces\ClpIECDomainParameters.pas"/>
         <UnitName Value="ClpIECDomainParameters"/>
-      </Item42>
-      <Item43>
+      </Item41>
+      <Item42>
         <Filename Value="..\..\Interfaces\ClpIECDsaSigner.pas"/>
         <UnitName Value="ClpIECDsaSigner"/>
-      </Item43>
-      <Item44>
+      </Item42>
+      <Item43>
         <Filename Value="..\..\Interfaces\ClpIECKeyGenerationParameters.pas"/>
         <UnitName Value="ClpIECKeyGenerationParameters"/>
-      </Item44>
-      <Item45>
+      </Item43>
+      <Item44>
         <Filename Value="..\..\Interfaces\ClpIECKeyPairGenerator.pas"/>
         <UnitName Value="ClpIECKeyPairGenerator"/>
-      </Item45>
-      <Item46>
+      </Item44>
+      <Item45>
         <Filename Value="..\..\Interfaces\ClpIECKeyParameters.pas"/>
         <UnitName Value="ClpIECKeyParameters"/>
-      </Item46>
-      <Item47>
+      </Item45>
+      <Item46>
         <Filename Value="..\..\Interfaces\ClpIECPrivateKeyParameters.pas"/>
         <UnitName Value="ClpIECPrivateKeyParameters"/>
-      </Item47>
-      <Item48>
+      </Item46>
+      <Item47>
         <Filename Value="..\..\Interfaces\ClpIECPublicKeyParameters.pas"/>
         <UnitName Value="ClpIECPublicKeyParameters"/>
-      </Item48>
-      <Item49>
+      </Item47>
+      <Item48>
         <Filename Value="..\..\Interfaces\ClpIExtensionField.pas"/>
         <UnitName Value="ClpIExtensionField"/>
-      </Item49>
-      <Item50>
+      </Item48>
+      <Item49>
         <Filename Value="..\..\Interfaces\ClpIFiniteField.pas"/>
         <UnitName Value="ClpIFiniteField"/>
+      </Item49>
+      <Item50>
+        <Filename Value="..\..\Interfaces\ClpIFixedPointPreCompInfo.pas"/>
+        <UnitName Value="ClpIFixedPointPreCompInfo"/>
       </Item50>
       <Item51>
-        <Filename Value="..\..\Interfaces\ClpIFixedPointCombMultiplier.pas"/>
-        <UnitName Value="ClpIFixedPointCombMultiplier"/>
+        <Filename Value="..\..\Interfaces\ClpIGenericPolynomialExtensionField.pas"/>
+        <UnitName Value="ClpIGenericPolynomialExtensionField"/>
       </Item51>
       <Item52>
-        <Filename Value="..\..\Interfaces\ClpIFixedPointPreCompInfo.pas"/>
-        <UnitName Value="ClpIFixedPointPreCompInfo"/>
+        <Filename Value="..\..\Interfaces\ClpIGF2Polynomial.pas"/>
+        <UnitName Value="ClpIGF2Polynomial"/>
       </Item52>
       <Item53>
-        <Filename Value="..\..\Interfaces\ClpIGenericPolynomialExtensionField.pas"/>
-        <UnitName Value="ClpIGenericPolynomialExtensionField"/>
+        <Filename Value="..\..\Interfaces\ClpIGlvEndomorphism.pas"/>
+        <UnitName Value="ClpIGlvEndomorphism"/>
       </Item53>
       <Item54>
-        <Filename Value="..\..\Interfaces\ClpIGF2Polynomial.pas"/>
-        <UnitName Value="ClpIGF2Polynomial"/>
+        <Filename Value="..\..\Interfaces\ClpIGlvTypeBEndomorphism.pas"/>
+        <UnitName Value="ClpIGlvTypeBEndomorphism"/>
       </Item54>
       <Item55>
-        <Filename Value="..\..\Interfaces\ClpIGlvEndomorphism.pas"/>
-        <UnitName Value="ClpIGlvEndomorphism"/>
+        <Filename Value="..\..\Interfaces\ClpIGlvTypeBParameters.pas"/>
+        <UnitName Value="ClpIGlvTypeBParameters"/>
       </Item55>
       <Item56>
-        <Filename Value="..\..\Interfaces\ClpIGlvMultiplier.pas"/>
-        <UnitName Value="ClpIGlvMultiplier"/>
+        <Filename Value="..\..\Interfaces\ClpIKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpIKeyGenerationParameters"/>
       </Item56>
       <Item57>
-        <Filename Value="..\..\Interfaces\ClpIGlvTypeBEndomorphism.pas"/>
-        <UnitName Value="ClpIGlvTypeBEndomorphism"/>
+        <Filename Value="..\..\Interfaces\ClpIOidTokenizer.pas"/>
+        <UnitName Value="ClpIOidTokenizer"/>
       </Item57>
       <Item58>
-        <Filename Value="..\..\Interfaces\ClpIGlvTypeBParameters.pas"/>
-        <UnitName Value="ClpIGlvTypeBParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIParametersWithRandom.pas"/>
+        <UnitName Value="ClpIParametersWithRandom"/>
       </Item58>
       <Item59>
-        <Filename Value="..\..\Interfaces\ClpIKeyGenerationParameters.pas"/>
-        <UnitName Value="ClpIKeyGenerationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIPolynomial.pas"/>
+        <UnitName Value="ClpIPolynomial"/>
       </Item59>
       <Item60>
-        <Filename Value="..\..\Interfaces\ClpIOidTokenizer.pas"/>
-        <UnitName Value="ClpIOidTokenizer"/>
+        <Filename Value="..\..\Interfaces\ClpIPolynomialExtensionField.pas"/>
+        <UnitName Value="ClpIPolynomialExtensionField"/>
       </Item60>
       <Item61>
-        <Filename Value="..\..\Interfaces\ClpIParametersWithRandom.pas"/>
-        <UnitName Value="ClpIParametersWithRandom"/>
+        <Filename Value="..\..\Interfaces\ClpIPreCompInfo.pas"/>
+        <UnitName Value="ClpIPreCompInfo"/>
       </Item61>
       <Item62>
-        <Filename Value="..\..\Interfaces\ClpIPolynomial.pas"/>
-        <UnitName Value="ClpIPolynomial"/>
+        <Filename Value="..\..\Interfaces\ClpIPrimeField.pas"/>
+        <UnitName Value="ClpIPrimeField"/>
       </Item62>
       <Item63>
-        <Filename Value="..\..\Interfaces\ClpIPolynomialExtensionField.pas"/>
-        <UnitName Value="ClpIPolynomialExtensionField"/>
+        <Filename Value="..\..\Interfaces\ClpIRandom.pas"/>
+        <UnitName Value="ClpIRandom"/>
       </Item63>
       <Item64>
-        <Filename Value="..\..\Interfaces\ClpIPreCompInfo.pas"/>
-        <UnitName Value="ClpIPreCompInfo"/>
+        <Filename Value="..\..\Interfaces\ClpIRandomDsaKCalculator.pas"/>
+        <UnitName Value="ClpIRandomDsaKCalculator"/>
       </Item64>
       <Item65>
-        <Filename Value="..\..\Interfaces\ClpIPrimeField.pas"/>
-        <UnitName Value="ClpIPrimeField"/>
+        <Filename Value="..\..\Interfaces\ClpIRandomGenerator.pas"/>
+        <UnitName Value="ClpIRandomGenerator"/>
       </Item65>
       <Item66>
-        <Filename Value="..\..\Interfaces\ClpIRandom.pas"/>
-        <UnitName Value="ClpIRandom"/>
+        <Filename Value="..\..\Interfaces\ClpIRandomNumberGenerator.pas"/>
+        <UnitName Value="ClpIRandomNumberGenerator"/>
       </Item66>
       <Item67>
-        <Filename Value="..\..\Interfaces\ClpIRandomDsaKCalculator.pas"/>
-        <UnitName Value="ClpIRandomDsaKCalculator"/>
+        <Filename Value="..\..\Interfaces\ClpIScaleXPointMap.pas"/>
+        <UnitName Value="ClpIScaleXPointMap"/>
       </Item67>
       <Item68>
-        <Filename Value="..\..\Interfaces\ClpIRandomGenerator.pas"/>
-        <UnitName Value="ClpIRandomGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpISecureRandom.pas"/>
+        <UnitName Value="ClpISecureRandom"/>
       </Item68>
       <Item69>
-        <Filename Value="..\..\Interfaces\ClpIRandomNumberGenerator.pas"/>
-        <UnitName Value="ClpIRandomNumberGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpISigner.pas"/>
+        <UnitName Value="ClpISigner"/>
       </Item69>
       <Item70>
-        <Filename Value="..\..\Interfaces\ClpIScaleXPointMap.pas"/>
-        <UnitName Value="ClpIScaleXPointMap"/>
+        <Filename Value="..\..\Interfaces\ClpIWNafPreCompInfo.pas"/>
+        <UnitName Value="ClpIWNafPreCompInfo"/>
       </Item70>
       <Item71>
-        <Filename Value="..\..\Interfaces\ClpISecureRandom.pas"/>
-        <UnitName Value="ClpISecureRandom"/>
+        <Filename Value="..\..\Interfaces\ClpIWTauNafPreCompInfo.pas"/>
+        <UnitName Value="ClpIWTauNafPreCompInfo"/>
       </Item71>
       <Item72>
-        <Filename Value="..\..\Interfaces\ClpISigner.pas"/>
-        <UnitName Value="ClpISigner"/>
+        <Filename Value="..\..\Interfaces\ClpIX9ECParameters.pas"/>
+        <UnitName Value="ClpIX9ECParameters"/>
       </Item72>
       <Item73>
-        <Filename Value="..\..\Interfaces\ClpIWNafL2RMultiplier.pas"/>
-        <UnitName Value="ClpIWNafL2RMultiplier"/>
+        <Filename Value="..\..\Interfaces\ClpIX9ECParametersHolder.pas"/>
+        <UnitName Value="ClpIX9ECParametersHolder"/>
       </Item73>
       <Item74>
-        <Filename Value="..\..\Interfaces\ClpIWNafPreCompInfo.pas"/>
-        <UnitName Value="ClpIWNafPreCompInfo"/>
+        <Filename Value="..\..\Interfaces\ClpIZTauElement.pas"/>
+        <UnitName Value="ClpIZTauElement"/>
       </Item74>
       <Item75>
-        <Filename Value="..\..\Interfaces\ClpIWTauNafMultiplier.pas"/>
-        <UnitName Value="ClpIWTauNafMultiplier"/>
+        <Filename Value="..\..\Math\ClpBigInteger.pas"/>
+        <UnitName Value="ClpBigInteger"/>
       </Item75>
       <Item76>
-        <Filename Value="..\..\Interfaces\ClpIWTauNafPreCompInfo.pas"/>
-        <UnitName Value="ClpIWTauNafPreCompInfo"/>
+        <Filename Value="..\..\Math\EC\ClpECAlgorithms.pas"/>
+        <UnitName Value="ClpECAlgorithms"/>
       </Item76>
       <Item77>
-        <Filename Value="..\..\Interfaces\ClpIX9ECParameters.pas"/>
-        <UnitName Value="ClpIX9ECParameters"/>
+        <Filename Value="..\..\Math\EC\ClpLongArray.pas"/>
+        <UnitName Value="ClpLongArray"/>
       </Item77>
       <Item78>
-        <Filename Value="..\..\Interfaces\ClpIX9ECParametersHolder.pas"/>
-        <UnitName Value="ClpIX9ECParametersHolder"/>
+        <Filename Value="..\..\Math\EC\ClpScaleXPointMap.pas"/>
+        <UnitName Value="ClpScaleXPointMap"/>
       </Item78>
       <Item79>
-        <Filename Value="..\..\Interfaces\ClpIZTauElement.pas"/>
-        <UnitName Value="ClpIZTauElement"/>
+        <Filename Value="..\..\Math\EC\Abc\ClpSimpleBigDecimal.pas"/>
+        <UnitName Value="ClpSimpleBigDecimal"/>
       </Item79>
       <Item80>
-        <Filename Value="..\..\Math\ClpBigInteger.pas"/>
-        <UnitName Value="ClpBigInteger"/>
+        <Filename Value="..\..\Math\EC\Abc\ClpTnaf.pas"/>
+        <UnitName Value="ClpTnaf"/>
       </Item80>
       <Item81>
-        <Filename Value="..\..\Math\EC\ClpECAlgorithms.pas"/>
-        <UnitName Value="ClpECAlgorithms"/>
+        <Filename Value="..\..\Math\EC\Abc\ClpZTauElement.pas"/>
+        <UnitName Value="ClpZTauElement"/>
       </Item81>
       <Item82>
-        <Filename Value="..\..\Math\EC\ClpLongArray.pas"/>
-        <UnitName Value="ClpLongArray"/>
+        <Filename Value="..\..\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas"/>
+        <UnitName Value="ClpGlvTypeBEndomorphism"/>
       </Item82>
       <Item83>
-        <Filename Value="..\..\Math\EC\ClpScaleXPointMap.pas"/>
-        <UnitName Value="ClpScaleXPointMap"/>
+        <Filename Value="..\..\Math\EC\Endo\ClpGlvTypeBParameters.pas"/>
+        <UnitName Value="ClpGlvTypeBParameters"/>
       </Item83>
       <Item84>
-        <Filename Value="..\..\Math\EC\Abc\ClpSimpleBigDecimal.pas"/>
-        <UnitName Value="ClpSimpleBigDecimal"/>
+        <Filename Value="..\..\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas"/>
+        <UnitName Value="ClpFixedPointPreCompInfo"/>
       </Item84>
       <Item85>
-        <Filename Value="..\..\Math\EC\Abc\ClpTnaf.pas"/>
-        <UnitName Value="ClpTnaf"/>
+        <Filename Value="..\..\Math\EC\Multiplier\ClpWNafPreCompInfo.pas"/>
+        <UnitName Value="ClpWNafPreCompInfo"/>
       </Item85>
       <Item86>
-        <Filename Value="..\..\Math\EC\Abc\ClpZTauElement.pas"/>
-        <UnitName Value="ClpZTauElement"/>
+        <Filename Value="..\..\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas"/>
+        <UnitName Value="ClpWTauNafPreCompInfo"/>
       </Item86>
       <Item87>
-        <Filename Value="..\..\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas"/>
-        <UnitName Value="ClpGlvTypeBEndomorphism"/>
+        <Filename Value="..\..\Math\Field\ClpFiniteFields.pas"/>
+        <UnitName Value="ClpFiniteFields"/>
       </Item87>
       <Item88>
-        <Filename Value="..\..\Math\EC\Endo\ClpGlvTypeBParameters.pas"/>
-        <UnitName Value="ClpGlvTypeBParameters"/>
+        <Filename Value="..\..\Math\Field\ClpGenericPolynomialExtensionField.pas"/>
+        <UnitName Value="ClpGenericPolynomialExtensionField"/>
       </Item88>
       <Item89>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpAbstractECMultiplier.pas"/>
-        <UnitName Value="ClpAbstractECMultiplier"/>
+        <Filename Value="..\..\Math\Field\ClpGF2Polynomial.pas"/>
+        <UnitName Value="ClpGF2Polynomial"/>
       </Item89>
       <Item90>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas"/>
-        <UnitName Value="ClpFixedPointCombMultiplier"/>
+        <Filename Value="..\..\Math\Field\ClpPrimeField.pas"/>
+        <UnitName Value="ClpPrimeField"/>
       </Item90>
       <Item91>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas"/>
-        <UnitName Value="ClpFixedPointPreCompInfo"/>
+        <Filename Value="..\..\Math\Raw\ClpMod.pas"/>
+        <UnitName Value="ClpMod"/>
       </Item91>
       <Item92>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpFixedPointUtilities.pas"/>
-        <UnitName Value="ClpFixedPointUtilities"/>
+        <Filename Value="..\..\Math\Raw\ClpNat.pas"/>
+        <UnitName Value="ClpNat"/>
       </Item92>
       <Item93>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpGlvMultiplier.pas"/>
-        <UnitName Value="ClpGlvMultiplier"/>
+        <Filename Value="..\..\Security\ClpDigestUtilities.pas"/>
+        <UnitName Value="ClpDigestUtilities"/>
       </Item93>
       <Item94>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas"/>
-        <UnitName Value="ClpWNafL2RMultiplier"/>
+        <Filename Value="..\..\Security\ClpRandom.pas"/>
+        <UnitName Value="ClpRandom"/>
       </Item94>
       <Item95>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpWNafPreCompInfo.pas"/>
-        <UnitName Value="ClpWNafPreCompInfo"/>
+        <Filename Value="..\..\Security\ClpSecureRandom.pas"/>
+        <UnitName Value="ClpSecureRandom"/>
       </Item95>
       <Item96>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpWTauNafMultiplier.pas"/>
-        <UnitName Value="ClpWTauNafMultiplier"/>
+        <Filename Value="..\..\Security\ClpSignerUtilities.pas"/>
+        <UnitName Value="ClpSignerUtilities"/>
       </Item96>
       <Item97>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas"/>
-        <UnitName Value="ClpWTauNafPreCompInfo"/>
+        <Filename Value="..\..\Utils\ClpArrayUtils.pas"/>
+        <UnitName Value="ClpArrayUtils"/>
       </Item97>
       <Item98>
-        <Filename Value="..\..\Math\Field\ClpFiniteFields.pas"/>
-        <UnitName Value="ClpFiniteFields"/>
+        <Filename Value="..\..\Utils\ClpBigIntegers.pas"/>
+        <UnitName Value="ClpBigIntegers"/>
       </Item98>
       <Item99>
-        <Filename Value="..\..\Math\Field\ClpGenericPolynomialExtensionField.pas"/>
-        <UnitName Value="ClpGenericPolynomialExtensionField"/>
+        <Filename Value="..\..\Utils\ClpBitConverter.pas"/>
+        <UnitName Value="ClpBitConverter"/>
       </Item99>
       <Item100>
-        <Filename Value="..\..\Math\Field\ClpGF2Polynomial.pas"/>
-        <UnitName Value="ClpGF2Polynomial"/>
+        <Filename Value="..\..\Utils\ClpBits.pas"/>
+        <UnitName Value="ClpBits"/>
       </Item100>
       <Item101>
-        <Filename Value="..\..\Math\Field\ClpPrimeField.pas"/>
-        <UnitName Value="ClpPrimeField"/>
+        <Filename Value="..\..\Utils\ClpConverters.pas"/>
+        <UnitName Value="ClpConverters"/>
       </Item101>
       <Item102>
-        <Filename Value="..\..\Math\Raw\ClpMod.pas"/>
-        <UnitName Value="ClpMod"/>
+        <Filename Value="..\..\Utils\ClpCryptoLibTypes.pas"/>
+        <UnitName Value="ClpCryptoLibTypes"/>
       </Item102>
       <Item103>
-        <Filename Value="..\..\Math\Raw\ClpNat.pas"/>
-        <UnitName Value="ClpNat"/>
+        <Filename Value="..\..\Utils\ClpTimes.pas"/>
+        <UnitName Value="ClpTimes"/>
       </Item103>
       <Item104>
-        <Filename Value="..\..\Security\ClpDigestUtilities.pas"/>
-        <UnitName Value="ClpDigestUtilities"/>
+        <Filename Value="..\..\Utils\Randoms\ClpOSRandom.pas"/>
+        <UnitName Value="ClpOSRandom"/>
       </Item104>
       <Item105>
-        <Filename Value="..\..\Security\ClpRandom.pas"/>
-        <UnitName Value="ClpRandom"/>
+        <Filename Value="..\..\Utils\Rng\ClpRandomNumberGenerator.pas"/>
+        <UnitName Value="ClpRandomNumberGenerator"/>
       </Item105>
       <Item106>
-        <Filename Value="..\..\Security\ClpSecureRandom.pas"/>
-        <UnitName Value="ClpSecureRandom"/>
+        <Filename Value="..\..\Utils\ClpSetWeakRef.pas"/>
+        <UnitName Value="ClpSetWeakRef"/>
       </Item106>
       <Item107>
-        <Filename Value="..\..\Security\ClpSignerUtilities.pas"/>
-        <UnitName Value="ClpSignerUtilities"/>
+        <Filename Value="..\..\Security\ClpParameterUtilities.pas"/>
+        <UnitName Value="ClpParameterUtilities"/>
       </Item107>
       <Item108>
-        <Filename Value="..\..\Utils\ClpArrayUtils.pas"/>
-        <UnitName Value="ClpArrayUtils"/>
+        <Filename Value="..\..\Security\ClpGeneratorUtilities.pas"/>
+        <UnitName Value="ClpGeneratorUtilities"/>
       </Item108>
       <Item109>
-        <Filename Value="..\..\Utils\ClpBigIntegers.pas"/>
-        <UnitName Value="ClpBigIntegers"/>
+        <Filename Value="..\..\Security\ClpCipherUtilities.pas"/>
+        <UnitName Value="ClpCipherUtilities"/>
       </Item109>
       <Item110>
-        <Filename Value="..\..\Utils\ClpBitConverter.pas"/>
-        <UnitName Value="ClpBitConverter"/>
+        <Filename Value="..\..\Interfaces\ClpIAesEngine.pas"/>
+        <UnitName Value="ClpIAesEngine"/>
       </Item110>
       <Item111>
-        <Filename Value="..\..\Utils\ClpBits.pas"/>
-        <UnitName Value="ClpBits"/>
+        <Filename Value="..\..\Interfaces\ClpIParametersWithIV.pas"/>
+        <UnitName Value="ClpIParametersWithIV"/>
       </Item111>
       <Item112>
-        <Filename Value="..\..\Utils\ClpConverters.pas"/>
-        <UnitName Value="ClpConverters"/>
+        <Filename Value="..\..\Interfaces\ClpIPaddedBufferedBlockCipher.pas"/>
+        <UnitName Value="ClpIPaddedBufferedBlockCipher"/>
       </Item112>
       <Item113>
-        <Filename Value="..\..\Utils\ClpCryptoLibTypes.pas"/>
-        <UnitName Value="ClpCryptoLibTypes"/>
+        <Filename Value="..\..\Interfaces\ClpIKeyParameter.pas"/>
+        <UnitName Value="ClpIKeyParameter"/>
       </Item113>
       <Item114>
-        <Filename Value="..\..\Utils\ClpTimes.pas"/>
-        <UnitName Value="ClpTimes"/>
+        <Filename Value="..\..\Interfaces\ClpIBufferedCipherBase.pas"/>
+        <UnitName Value="ClpIBufferedCipherBase"/>
       </Item114>
       <Item115>
-        <Filename Value="..\..\Utils\Randoms\ClpOSRandom.pas"/>
-        <UnitName Value="ClpOSRandom"/>
+        <Filename Value="..\..\Interfaces\ClpIBufferedCipher.pas"/>
+        <UnitName Value="ClpIBufferedCipher"/>
       </Item115>
       <Item116>
-        <Filename Value="..\..\Utils\Rng\ClpRandomNumberGenerator.pas"/>
-        <UnitName Value="ClpRandomNumberGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIBufferedBlockCipher.pas"/>
+        <UnitName Value="ClpIBufferedBlockCipher"/>
       </Item116>
       <Item117>
-        <Filename Value="..\..\Utils\ClpSetWeakRef.pas"/>
-        <UnitName Value="ClpSetWeakRef"/>
+        <Filename Value="..\..\Interfaces\ClpIBlockCipherPadding.pas"/>
+        <UnitName Value="ClpIBlockCipherPadding"/>
       </Item117>
       <Item118>
-        <Filename Value="..\..\Security\ClpParameterUtilities.pas"/>
-        <UnitName Value="ClpParameterUtilities"/>
+        <Filename Value="..\..\Interfaces\ClpIBlockCipher.pas"/>
+        <UnitName Value="ClpIBlockCipher"/>
       </Item118>
       <Item119>
-        <Filename Value="..\..\Security\ClpGeneratorUtilities.pas"/>
-        <UnitName Value="ClpGeneratorUtilities"/>
+        <Filename Value="..\..\Crypto\Paddings\ClpPaddedBufferedBlockCipher.pas"/>
+        <UnitName Value="ClpPaddedBufferedBlockCipher"/>
       </Item119>
       <Item120>
-        <Filename Value="..\..\Security\ClpCipherUtilities.pas"/>
-        <UnitName Value="ClpCipherUtilities"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpParametersWithIV.pas"/>
+        <UnitName Value="ClpParametersWithIV"/>
       </Item120>
       <Item121>
-        <Filename Value="..\..\Interfaces\ClpIAesEngine.pas"/>
-        <UnitName Value="ClpIAesEngine"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpKeyParameter.pas"/>
+        <UnitName Value="ClpKeyParameter"/>
       </Item121>
       <Item122>
-        <Filename Value="..\..\Interfaces\ClpIParametersWithIV.pas"/>
-        <UnitName Value="ClpIParametersWithIV"/>
+        <Filename Value="..\..\Crypto\ClpBufferedBlockCipher.pas"/>
+        <UnitName Value="ClpBufferedBlockCipher"/>
       </Item122>
       <Item123>
-        <Filename Value="..\..\Interfaces\ClpIPaddedBufferedBlockCipher.pas"/>
-        <UnitName Value="ClpIPaddedBufferedBlockCipher"/>
+        <Filename Value="..\..\Crypto\ClpBufferedCipherBase.pas"/>
+        <UnitName Value="ClpBufferedCipherBase"/>
       </Item123>
       <Item124>
-        <Filename Value="..\..\Interfaces\ClpIKeyParameter.pas"/>
-        <UnitName Value="ClpIKeyParameter"/>
+        <Filename Value="..\..\Utils\ClpCheck.pas"/>
+        <UnitName Value="ClpCheck"/>
       </Item124>
       <Item125>
-        <Filename Value="..\..\Interfaces\ClpIBufferedCipherBase.pas"/>
-        <UnitName Value="ClpIBufferedCipherBase"/>
+        <Filename Value="..\..\Crypto\Engines\ClpAesEngine.pas"/>
+        <UnitName Value="ClpAesEngine"/>
       </Item125>
       <Item126>
-        <Filename Value="..\..\Interfaces\ClpIBufferedCipher.pas"/>
-        <UnitName Value="ClpIBufferedCipher"/>
+        <Filename Value="..\..\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpPascalCoinECIESKdfBytesGenerator"/>
       </Item126>
       <Item127>
-        <Filename Value="..\..\Interfaces\ClpIBufferedBlockCipher.pas"/>
-        <UnitName Value="ClpIBufferedBlockCipher"/>
+        <Filename Value="..\..\Crypto\Engines\ClpPascalCoinIESEngine.pas"/>
+        <UnitName Value="ClpPascalCoinIESEngine"/>
       </Item127>
       <Item128>
-        <Filename Value="..\..\Interfaces\ClpIBlockCipherPadding.pas"/>
-        <UnitName Value="ClpIBlockCipherPadding"/>
+        <Filename Value="..\..\Crypto\Generators\ClpBaseKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpBaseKdfBytesGenerator"/>
       </Item128>
       <Item129>
-        <Filename Value="..\..\Interfaces\ClpIBlockCipher.pas"/>
-        <UnitName Value="ClpIBlockCipher"/>
+        <Filename Value="..\..\Crypto\Engines\ClpIESEngine.pas"/>
+        <UnitName Value="ClpIESEngine"/>
       </Item129>
       <Item130>
-        <Filename Value="..\..\Crypto\Paddings\ClpPaddedBufferedBlockCipher.pas"/>
-        <UnitName Value="ClpPaddedBufferedBlockCipher"/>
+        <Filename Value="..\..\Crypto\Parsers\ClpECIESPublicKeyParser.pas"/>
+        <UnitName Value="ClpECIESPublicKeyParser"/>
       </Item130>
       <Item131>
-        <Filename Value="..\..\Crypto\Parameters\ClpParametersWithIV.pas"/>
-        <UnitName Value="ClpParametersWithIV"/>
+        <Filename Value="..\..\Crypto\ClpIESCipher.pas"/>
+        <UnitName Value="ClpIESCipher"/>
       </Item131>
       <Item132>
-        <Filename Value="..\..\Crypto\Parameters\ClpKeyParameter.pas"/>
-        <UnitName Value="ClpKeyParameter"/>
+        <Filename Value="..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas"/>
+        <UnitName Value="ClpECDHBasicAgreement"/>
       </Item132>
       <Item133>
-        <Filename Value="..\..\Crypto\ClpBufferedBlockCipher.pas"/>
-        <UnitName Value="ClpBufferedBlockCipher"/>
+        <Filename Value="..\..\Crypto\ClpEphemeralKeyPair.pas"/>
+        <UnitName Value="ClpEphemeralKeyPair"/>
       </Item133>
       <Item134>
-        <Filename Value="..\..\Crypto\ClpBufferedCipherBase.pas"/>
-        <UnitName Value="ClpBufferedCipherBase"/>
+        <Filename Value="..\..\Crypto\ClpKeyEncoder.pas"/>
+        <UnitName Value="ClpKeyEncoder"/>
       </Item134>
       <Item135>
-        <Filename Value="..\..\Utils\ClpCheck.pas"/>
-        <UnitName Value="ClpCheck"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpIESWithCipherParameters.pas"/>
+        <UnitName Value="ClpIESWithCipherParameters"/>
       </Item135>
       <Item136>
-        <Filename Value="..\..\Crypto\Engines\ClpAesEngine.pas"/>
-        <UnitName Value="ClpAesEngine"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpIESParameters.pas"/>
+        <UnitName Value="ClpIESParameters"/>
       </Item136>
       <Item137>
-        <Filename Value="..\..\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas"/>
-        <UnitName Value="ClpPascalCoinECIESKdfBytesGenerator"/>
+        <Filename Value="..\..\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas"/>
+        <UnitName Value="ClpEphemeralKeyPairGenerator"/>
       </Item137>
       <Item138>
-        <Filename Value="..\..\Crypto\Engines\ClpPascalCoinIESEngine.pas"/>
-        <UnitName Value="ClpPascalCoinIESEngine"/>
+        <Filename Value="..\..\Crypto\Generators\ClpKdf2BytesGenerator.pas"/>
+        <UnitName Value="ClpKdf2BytesGenerator"/>
       </Item138>
       <Item139>
-        <Filename Value="..\..\Crypto\Generators\ClpBaseKdfBytesGenerator.pas"/>
-        <UnitName Value="ClpBaseKdfBytesGenerator"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpIso18033KdfParameters.pas"/>
+        <UnitName Value="ClpIso18033KdfParameters"/>
       </Item139>
       <Item140>
-        <Filename Value="..\..\Crypto\Engines\ClpIESEngine.pas"/>
-        <UnitName Value="ClpIESEngine"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpKdfParameters.pas"/>
+        <UnitName Value="ClpKdfParameters"/>
       </Item140>
       <Item141>
-        <Filename Value="..\..\Crypto\Parsers\ClpECIESPublicKeyParser.pas"/>
-        <UnitName Value="ClpECIESPublicKeyParser"/>
+        <Filename Value="..\..\Interfaces\ClpIIESWithCipherParameters.pas"/>
+        <UnitName Value="ClpIIESWithCipherParameters"/>
       </Item141>
       <Item142>
-        <Filename Value="..\..\Crypto\ClpIESCipher.pas"/>
-        <UnitName Value="ClpIESCipher"/>
+        <Filename Value="..\..\Interfaces\ClpIIESParameters.pas"/>
+        <UnitName Value="ClpIIESParameters"/>
       </Item142>
       <Item143>
-        <Filename Value="..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas"/>
-        <UnitName Value="ClpECDHBasicAgreement"/>
+        <Filename Value="..\..\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpIPascalCoinECIESKdfBytesGenerator"/>
       </Item143>
       <Item144>
-        <Filename Value="..\..\Crypto\ClpEphemeralKeyPair.pas"/>
-        <UnitName Value="ClpEphemeralKeyPair"/>
+        <Filename Value="..\..\Interfaces\ClpIPascalCoinIESEngine.pas"/>
+        <UnitName Value="ClpIPascalCoinIESEngine"/>
       </Item144>
       <Item145>
-        <Filename Value="..\..\Crypto\ClpKeyEncoder.pas"/>
-        <UnitName Value="ClpKeyEncoder"/>
+        <Filename Value="..\..\Interfaces\ClpIIESEngine.pas"/>
+        <UnitName Value="ClpIIESEngine"/>
       </Item145>
       <Item146>
-        <Filename Value="..\..\Crypto\Parameters\ClpIESWithCipherParameters.pas"/>
-        <UnitName Value="ClpIESWithCipherParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIIESCipher.pas"/>
+        <UnitName Value="ClpIIESCipher"/>
       </Item146>
       <Item147>
-        <Filename Value="..\..\Crypto\Parameters\ClpIESParameters.pas"/>
-        <UnitName Value="ClpIESParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIECIESPublicKeyParser.pas"/>
+        <UnitName Value="ClpIECIESPublicKeyParser"/>
       </Item147>
       <Item148>
-        <Filename Value="..\..\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas"/>
-        <UnitName Value="ClpEphemeralKeyPairGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIEphemeralKeyPairGenerator"/>
       </Item148>
       <Item149>
-        <Filename Value="..\..\Crypto\Generators\ClpKdf2BytesGenerator.pas"/>
-        <UnitName Value="ClpKdf2BytesGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPair.pas"/>
+        <UnitName Value="ClpIEphemeralKeyPair"/>
       </Item149>
       <Item150>
-        <Filename Value="..\..\Crypto\Parameters\ClpIso18033KdfParameters.pas"/>
-        <UnitName Value="ClpIso18033KdfParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIKeyParser.pas"/>
+        <UnitName Value="ClpIKeyParser"/>
       </Item150>
       <Item151>
-        <Filename Value="..\..\Crypto\Parameters\ClpKdfParameters.pas"/>
-        <UnitName Value="ClpKdfParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIKdf2BytesGenerator.pas"/>
+        <UnitName Value="ClpIKdf2BytesGenerator"/>
       </Item151>
       <Item152>
-        <Filename Value="..\..\Interfaces\ClpIIESWithCipherParameters.pas"/>
-        <UnitName Value="ClpIIESWithCipherParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIBaseKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpIBaseKdfBytesGenerator"/>
       </Item152>
       <Item153>
-        <Filename Value="..\..\Interfaces\ClpIIESParameters.pas"/>
-        <UnitName Value="ClpIIESParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIIso18033KdfParameters.pas"/>
+        <UnitName Value="ClpIIso18033KdfParameters"/>
       </Item153>
       <Item154>
-        <Filename Value="..\..\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas"/>
-        <UnitName Value="ClpIPascalCoinECIESKdfBytesGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIKdfParameters.pas"/>
+        <UnitName Value="ClpIKdfParameters"/>
       </Item154>
       <Item155>
-        <Filename Value="..\..\Interfaces\ClpIPascalCoinIESEngine.pas"/>
-        <UnitName Value="ClpIPascalCoinIESEngine"/>
+        <Filename Value="..\..\Interfaces\ClpIDerivationFunction.pas"/>
+        <UnitName Value="ClpIDerivationFunction"/>
       </Item155>
       <Item156>
-        <Filename Value="..\..\Interfaces\ClpIIESEngine.pas"/>
-        <UnitName Value="ClpIIESEngine"/>
+        <Filename Value="..\..\Interfaces\ClpIDerivationParameters.pas"/>
+        <UnitName Value="ClpIDerivationParameters"/>
       </Item156>
       <Item157>
-        <Filename Value="..\..\Interfaces\ClpIIESCipher.pas"/>
-        <UnitName Value="ClpIIESCipher"/>
+        <Filename Value="..\..\Interfaces\ClpIECDHBasicAgreement.pas"/>
+        <UnitName Value="ClpIECDHBasicAgreement"/>
       </Item157>
       <Item158>
-        <Filename Value="..\..\Interfaces\ClpIECIESPublicKeyParser.pas"/>
-        <UnitName Value="ClpIECIESPublicKeyParser"/>
+        <Filename Value="..\..\Interfaces\ClpIBasicAgreement.pas"/>
+        <UnitName Value="ClpIBasicAgreement"/>
       </Item158>
       <Item159>
-        <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPairGenerator.pas"/>
-        <UnitName Value="ClpIEphemeralKeyPairGenerator"/>
+        <Filename Value="..\..\Crypto\Generators\ClpCipherKeyGenerator.pas"/>
+        <UnitName Value="ClpCipherKeyGenerator"/>
       </Item159>
       <Item160>
-        <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPair.pas"/>
-        <UnitName Value="ClpIEphemeralKeyPair"/>
+        <Filename Value="..\..\Utils\ClpStringUtils.pas"/>
+        <UnitName Value="ClpStringUtils"/>
       </Item160>
       <Item161>
-        <Filename Value="..\..\Interfaces\ClpIKeyParser.pas"/>
-        <UnitName Value="ClpIKeyParser"/>
+        <Filename Value="..\..\Interfaces\ClpICipherKeyGenerator.pas"/>
+        <UnitName Value="ClpICipherKeyGenerator"/>
       </Item161>
       <Item162>
-        <Filename Value="..\..\Interfaces\ClpIKdf2BytesGenerator.pas"/>
-        <UnitName Value="ClpIKdf2BytesGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDigest.pas"/>
+        <UnitName Value="ClpIDigest"/>
       </Item162>
       <Item163>
-        <Filename Value="..\..\Interfaces\ClpIBaseKdfBytesGenerator.pas"/>
-        <UnitName Value="ClpIBaseKdfBytesGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIStreamCipher.pas"/>
+        <UnitName Value="ClpIStreamCipher"/>
       </Item163>
       <Item164>
-        <Filename Value="..\..\Interfaces\ClpIIso18033KdfParameters.pas"/>
-        <UnitName Value="ClpIIso18033KdfParameters"/>
+        <Filename Value="CryptoLib4PascalPackage.pas"/>
+        <AddToUsesPkgSection Value="False"/>
+        <UnitName Value="CryptoLib4PascalPackage"/>
       </Item164>
       <Item165>
-        <Filename Value="..\..\Interfaces\ClpIKdfParameters.pas"/>
-        <UnitName Value="ClpIKdfParameters"/>
+        <Filename Value="..\..\Crypto\Generators\ClpPkcs5S2ParametersGenerator.pas"/>
+        <UnitName Value="ClpPkcs5S2ParametersGenerator"/>
       </Item165>
       <Item166>
-        <Filename Value="..\..\Interfaces\ClpIDerivationFunction.pas"/>
-        <UnitName Value="ClpIDerivationFunction"/>
+        <Filename Value="..\..\Interfaces\ClpIPkcs5S2ParametersGenerator.pas"/>
+        <UnitName Value="ClpIPkcs5S2ParametersGenerator"/>
       </Item166>
       <Item167>
-        <Filename Value="..\..\Interfaces\ClpIDerivationParameters.pas"/>
-        <UnitName Value="ClpIDerivationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIPbeParametersGenerator.pas"/>
+        <UnitName Value="ClpIPbeParametersGenerator"/>
       </Item167>
       <Item168>
-        <Filename Value="..\..\Interfaces\ClpIECDHBasicAgreement.pas"/>
-        <UnitName Value="ClpIECDHBasicAgreement"/>
+        <Filename Value="..\..\Crypto\Generators\ClpPbeParametersGenerator.pas"/>
+        <UnitName Value="ClpPbeParametersGenerator"/>
       </Item168>
       <Item169>
-        <Filename Value="..\..\Interfaces\ClpIBasicAgreement.pas"/>
-        <UnitName Value="ClpIBasicAgreement"/>
+        <Filename Value="..\..\Crypto\Macs\ClpHMac.pas"/>
+        <UnitName Value="ClpHMac"/>
       </Item169>
       <Item170>
-        <Filename Value="..\..\Crypto\Generators\ClpCipherKeyGenerator.pas"/>
-        <UnitName Value="ClpCipherKeyGenerator"/>
+        <Filename Value="..\..\Asn1\Misc\ClpMiscObjectIdentifiers.pas"/>
+        <UnitName Value="ClpMiscObjectIdentifiers"/>
       </Item170>
       <Item171>
-        <Filename Value="..\..\Utils\ClpStringUtils.pas"/>
-        <UnitName Value="ClpStringUtils"/>
+        <Filename Value="..\..\Asn1\Iana\ClpIanaObjectIdentifiers.pas"/>
+        <UnitName Value="ClpIanaObjectIdentifiers"/>
       </Item171>
       <Item172>
-        <Filename Value="..\..\Interfaces\ClpICipherKeyGenerator.pas"/>
-        <UnitName Value="ClpICipherKeyGenerator"/>
+        <Filename Value="..\..\Security\ClpMacUtilities.pas"/>
+        <UnitName Value="ClpMacUtilities"/>
       </Item172>
       <Item173>
-        <Filename Value="..\..\Interfaces\ClpIDigest.pas"/>
-        <UnitName Value="ClpIDigest"/>
+        <Filename Value="..\..\Interfaces\ClpIMac.pas"/>
+        <UnitName Value="ClpIMac"/>
       </Item173>
       <Item174>
-        <Filename Value="..\..\Interfaces\ClpIStreamCipher.pas"/>
-        <UnitName Value="ClpIStreamCipher"/>
+        <Filename Value="..\..\Interfaces\ClpIHMac.pas"/>
+        <UnitName Value="ClpIHMac"/>
       </Item174>
       <Item175>
-        <Filename Value="CryptoLib4PascalPackage.pas"/>
-        <AddToUsesPkgSection Value="False"/>
-        <UnitName Value="CryptoLib4PascalPackage"/>
+        <Filename Value="..\..\Crypto\Signers\ClpDsaSigner.pas"/>
+        <UnitName Value="ClpDsaSigner"/>
       </Item175>
       <Item176>
-        <Filename Value="..\..\Crypto\Generators\ClpPkcs5S2ParametersGenerator.pas"/>
-        <UnitName Value="ClpPkcs5S2ParametersGenerator"/>
+        <Filename Value="..\..\Crypto\Generators\ClpDsaKeyPairGenerator.pas"/>
+        <UnitName Value="ClpDsaKeyPairGenerator"/>
       </Item176>
       <Item177>
-        <Filename Value="..\..\Interfaces\ClpIPkcs5S2ParametersGenerator.pas"/>
-        <UnitName Value="ClpIPkcs5S2ParametersGenerator"/>
+        <Filename Value="..\..\Crypto\Signers\ClpECNRSigner.pas"/>
+        <UnitName Value="ClpECNRSigner"/>
       </Item177>
       <Item178>
-        <Filename Value="..\..\Interfaces\ClpIPbeParametersGenerator.pas"/>
-        <UnitName Value="ClpIPbeParametersGenerator"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDsaKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpDsaKeyGenerationParameters"/>
       </Item178>
       <Item179>
-        <Filename Value="..\..\Crypto\Generators\ClpPbeParametersGenerator.pas"/>
-        <UnitName Value="ClpPbeParametersGenerator"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDsaPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpDsaPrivateKeyParameters"/>
       </Item179>
       <Item180>
-        <Filename Value="..\..\Crypto\Macs\ClpHMac.pas"/>
-        <UnitName Value="ClpHMac"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDsaPublicKeyParameters.pas"/>
+        <UnitName Value="ClpDsaPublicKeyParameters"/>
       </Item180>
       <Item181>
-        <Filename Value="..\..\Asn1\Misc\ClpMiscObjectIdentifiers.pas"/>
-        <UnitName Value="ClpMiscObjectIdentifiers"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDsaValidationParameters.pas"/>
+        <UnitName Value="ClpDsaValidationParameters"/>
       </Item181>
       <Item182>
-        <Filename Value="..\..\Asn1\Iana\ClpIanaObjectIdentifiers.pas"/>
-        <UnitName Value="ClpIanaObjectIdentifiers"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDsaParameters.pas"/>
+        <UnitName Value="ClpDsaParameters"/>
       </Item182>
       <Item183>
-        <Filename Value="..\..\Security\ClpMacUtilities.pas"/>
-        <UnitName Value="ClpMacUtilities"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDsaKeyParameters.pas"/>
+        <UnitName Value="ClpDsaKeyParameters"/>
       </Item183>
       <Item184>
-        <Filename Value="..\..\Interfaces\ClpIMac.pas"/>
-        <UnitName Value="ClpIMac"/>
+        <Filename Value="..\..\Interfaces\ClpIECNRSigner.pas"/>
+        <UnitName Value="ClpIECNRSigner"/>
       </Item184>
       <Item185>
-        <Filename Value="..\..\Interfaces\ClpIHMac.pas"/>
-        <UnitName Value="ClpIHMac"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaSigner.pas"/>
+        <UnitName Value="ClpIDsaSigner"/>
       </Item185>
       <Item186>
-        <Filename Value="..\..\Crypto\Signers\ClpDsaSigner.pas"/>
-        <UnitName Value="ClpDsaSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIDsaKeyPairGenerator"/>
       </Item186>
       <Item187>
-        <Filename Value="..\..\Crypto\Generators\ClpDsaKeyPairGenerator.pas"/>
-        <UnitName Value="ClpDsaKeyPairGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpIDsaPrivateKeyParameters"/>
       </Item187>
       <Item188>
-        <Filename Value="..\..\Crypto\Signers\ClpECNRSigner.pas"/>
-        <UnitName Value="ClpECNRSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpIDsaKeyGenerationParameters"/>
       </Item188>
       <Item189>
-        <Filename Value="..\..\Crypto\Parameters\ClpDsaKeyGenerationParameters.pas"/>
-        <UnitName Value="ClpDsaKeyGenerationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaKeyParameters.pas"/>
+        <UnitName Value="ClpIDsaKeyParameters"/>
       </Item189>
       <Item190>
-        <Filename Value="..\..\Crypto\Parameters\ClpDsaPrivateKeyParameters.pas"/>
-        <UnitName Value="ClpDsaPrivateKeyParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaPublicKeyParameters.pas"/>
+        <UnitName Value="ClpIDsaPublicKeyParameters"/>
       </Item190>
       <Item191>
-        <Filename Value="..\..\Crypto\Parameters\ClpDsaPublicKeyParameters.pas"/>
-        <UnitName Value="ClpDsaPublicKeyParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaParameters.pas"/>
+        <UnitName Value="ClpIDsaParameters"/>
       </Item191>
       <Item192>
-        <Filename Value="..\..\Crypto\Parameters\ClpDsaValidationParameters.pas"/>
-        <UnitName Value="ClpDsaValidationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaValidationParameters.pas"/>
+        <UnitName Value="ClpIDsaValidationParameters"/>
       </Item192>
       <Item193>
-        <Filename Value="..\..\Crypto\Parameters\ClpDsaParameters.pas"/>
-        <UnitName Value="ClpDsaParameters"/>
+        <Filename Value="..\..\Crypto\Digests\ClpDigest.pas"/>
+        <UnitName Value="ClpDigest"/>
       </Item193>
       <Item194>
-        <Filename Value="..\..\Crypto\Parameters\ClpDsaKeyParameters.pas"/>
-        <UnitName Value="ClpDsaKeyParameters"/>
+        <Filename Value="..\..\Crypto\Agreement\ClpECDHCBasicAgreement.pas"/>
+        <UnitName Value="ClpECDHCBasicAgreement"/>
       </Item194>
       <Item195>
-        <Filename Value="..\..\Interfaces\ClpIECNRSigner.pas"/>
-        <UnitName Value="ClpIECNRSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIECDHCBasicAgreement.pas"/>
+        <UnitName Value="ClpIECDHCBasicAgreement"/>
       </Item195>
       <Item196>
-        <Filename Value="..\..\Interfaces\ClpIDsaSigner.pas"/>
-        <UnitName Value="ClpIDsaSigner"/>
+        <Filename Value="..\..\Crypto\Signers\ClpHMacDsaKCalculator.pas"/>
+        <UnitName Value="ClpHMacDsaKCalculator"/>
       </Item196>
       <Item197>
-        <Filename Value="..\..\Interfaces\ClpIDsaKeyPairGenerator.pas"/>
-        <UnitName Value="ClpIDsaKeyPairGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIHMacDsaKCalculator.pas"/>
+        <UnitName Value="ClpIHMacDsaKCalculator"/>
       </Item197>
       <Item198>
-        <Filename Value="..\..\Interfaces\ClpIDsaPrivateKeyParameters.pas"/>
-        <UnitName Value="ClpIDsaPrivateKeyParameters"/>
+        <Filename Value="..\..\Crypto\Generators\ClpHkdfBytesGenerator.pas"/>
+        <UnitName Value="ClpHkdfBytesGenerator"/>
       </Item198>
       <Item199>
-        <Filename Value="..\..\Interfaces\ClpIDsaKeyGenerationParameters.pas"/>
-        <UnitName Value="ClpIDsaKeyGenerationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIHkdfBytesGenerator.pas"/>
+        <UnitName Value="ClpIHkdfBytesGenerator"/>
       </Item199>
       <Item200>
-        <Filename Value="..\..\Interfaces\ClpIDsaKeyParameters.pas"/>
-        <UnitName Value="ClpIDsaKeyParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpHkdfParameters.pas"/>
+        <UnitName Value="ClpHkdfParameters"/>
       </Item200>
       <Item201>
-        <Filename Value="..\..\Interfaces\ClpIDsaPublicKeyParameters.pas"/>
-        <UnitName Value="ClpIDsaPublicKeyParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIHkdfParameters.pas"/>
+        <UnitName Value="ClpIHkdfParameters"/>
       </Item201>
       <Item202>
-        <Filename Value="..\..\Interfaces\ClpIDsaParameters.pas"/>
-        <UnitName Value="ClpIDsaParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas"/>
+        <UnitName Value="ClpDsaParameterGenerationParameters"/>
       </Item202>
       <Item203>
-        <Filename Value="..\..\Interfaces\ClpIDsaValidationParameters.pas"/>
-        <UnitName Value="ClpIDsaValidationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaParameterGenerationParameters.pas"/>
+        <UnitName Value="ClpIDsaParameterGenerationParameters"/>
       </Item203>
       <Item204>
-        <Filename Value="..\..\Crypto\Digests\ClpDigest.pas"/>
-        <UnitName Value="ClpDigest"/>
+        <Filename Value="..\..\Crypto\Generators\ClpDsaParametersGenerator.pas"/>
+        <UnitName Value="ClpDsaParametersGenerator"/>
       </Item204>
       <Item205>
-        <Filename Value="..\..\Crypto\Agreement\ClpECDHCBasicAgreement.pas"/>
-        <UnitName Value="ClpECDHCBasicAgreement"/>
+        <Filename Value="..\..\Asn1\X509\ClpDsaParameter.pas"/>
+        <UnitName Value="ClpDsaParameter"/>
       </Item205>
       <Item206>
-        <Filename Value="..\..\Interfaces\ClpIECDHCBasicAgreement.pas"/>
-        <UnitName Value="ClpIECDHCBasicAgreement"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaParameter.pas"/>
+        <UnitName Value="ClpIDsaParameter"/>
       </Item206>
       <Item207>
-        <Filename Value="..\..\Crypto\Signers\ClpHMacDsaKCalculator.pas"/>
-        <UnitName Value="ClpHMacDsaKCalculator"/>
+        <Filename Value="..\..\Interfaces\ClpIKeyEncoder.pas"/>
+        <UnitName Value="ClpIKeyEncoder"/>
       </Item207>
       <Item208>
-        <Filename Value="..\..\Interfaces\ClpIHMacDsaKCalculator.pas"/>
-        <UnitName Value="ClpIHMacDsaKCalculator"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaParametersGenerator.pas"/>
+        <UnitName Value="ClpIDsaParametersGenerator"/>
       </Item208>
       <Item209>
-        <Filename Value="..\..\Crypto\Generators\ClpHkdfBytesGenerator.pas"/>
-        <UnitName Value="ClpHkdfBytesGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIPreCompCallBack.pas"/>
+        <UnitName Value="ClpIPreCompCallBack"/>
       </Item209>
       <Item210>
-        <Filename Value="..\..\Interfaces\ClpIHkdfBytesGenerator.pas"/>
-        <UnitName Value="ClpIHkdfBytesGenerator"/>
+        <Filename Value="..\..\Asn1\Nist\ClpNistNamedCurves.pas"/>
+        <UnitName Value="ClpNistNamedCurves"/>
       </Item210>
       <Item211>
-        <Filename Value="..\..\Crypto\Parameters\ClpHkdfParameters.pas"/>
-        <UnitName Value="ClpHkdfParameters"/>
+        <Filename Value="..\..\Math\Raw\ClpNat256.pas"/>
+        <UnitName Value="ClpNat256"/>
       </Item211>
       <Item212>
-        <Filename Value="..\..\Interfaces\ClpIHkdfParameters.pas"/>
-        <UnitName Value="ClpIHkdfParameters"/>
+        <Filename Value="..\..\Math\Raw\ClpNat320.pas"/>
+        <UnitName Value="ClpNat320"/>
       </Item212>
       <Item213>
-        <Filename Value="..\..\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas"/>
-        <UnitName Value="ClpDsaParameterGenerationParameters"/>
+        <Filename Value="..\..\Crypto\Engines\ClpAesLightEngine.pas"/>
+        <UnitName Value="ClpAesLightEngine"/>
       </Item213>
       <Item214>
-        <Filename Value="..\..\Interfaces\ClpIDsaParameterGenerationParameters.pas"/>
-        <UnitName Value="ClpIDsaParameterGenerationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIAesLightEngine.pas"/>
+        <UnitName Value="ClpIAesLightEngine"/>
       </Item214>
       <Item215>
-        <Filename Value="..\..\Interfaces\ClpIValidityPrecompInfo.pas"/>
-        <UnitName Value="ClpIValidityPrecompInfo"/>
+        <Filename Value="..\..\Crypto\EC\ClpCustomNamedCurves.pas"/>
+        <UnitName Value="ClpCustomNamedCurves"/>
       </Item215>
       <Item216>
-        <Filename Value="..\..\Crypto\Generators\ClpDsaParametersGenerator.pas"/>
-        <UnitName Value="ClpDsaParametersGenerator"/>
+        <Filename Value="..\..\Math\Raw\ClpNat384.pas"/>
+        <UnitName Value="ClpNat384"/>
       </Item216>
       <Item217>
-        <Filename Value="..\..\Asn1\X509\ClpDsaParameter.pas"/>
-        <UnitName Value="ClpDsaParameter"/>
+        <Filename Value="..\..\Math\Raw\ClpNat192.pas"/>
+        <UnitName Value="ClpNat192"/>
       </Item217>
       <Item218>
-        <Filename Value="..\..\Interfaces\ClpIDsaParameter.pas"/>
-        <UnitName Value="ClpIDsaParameter"/>
+        <Filename Value="..\..\Math\Raw\ClpNat512.pas"/>
+        <UnitName Value="ClpNat512"/>
       </Item218>
       <Item219>
-        <Filename Value="..\..\Interfaces\ClpIKeyEncoder.pas"/>
-        <UnitName Value="ClpIKeyEncoder"/>
+        <Filename Value="..\..\Math\Raw\ClpInterleave.pas"/>
+        <UnitName Value="ClpInterleave"/>
       </Item219>
       <Item220>
-        <Filename Value="..\..\Interfaces\ClpIDsaParametersGenerator.pas"/>
-        <UnitName Value="ClpIDsaParametersGenerator"/>
+        <Filename Value="..\..\Asn1\Bsi\ClpBsiObjectIdentifiers.pas"/>
+        <UnitName Value="ClpBsiObjectIdentifiers"/>
       </Item220>
       <Item221>
-        <Filename Value="..\..\Interfaces\ClpIPreCompCallBack.pas"/>
-        <UnitName Value="ClpIPreCompCallBack"/>
+        <Filename Value="..\..\Asn1\Eac\ClpEacObjectIdentifiers.pas"/>
+        <UnitName Value="ClpEacObjectIdentifiers"/>
       </Item221>
       <Item222>
-        <Filename Value="..\..\Math\EC\Multiplier\ClpValidityPrecompInfo.pas"/>
-        <AddToUsesPkgSection Value="False"/>
-        <UnitName Value="ClpValidityPrecompInfo"/>
+        <Filename Value="..\..\Interfaces\ClpIDsaExt.pas"/>
+        <UnitName Value="ClpIDsaExt"/>
       </Item222>
       <Item223>
-        <Filename Value="..\..\Asn1\Nist\ClpNistNamedCurves.pas"/>
-        <UnitName Value="ClpNistNamedCurves"/>
+        <Filename Value="..\..\Interfaces\ClpISchnorrDigestSigner.pas"/>
+        <UnitName Value="ClpISchnorrDigestSigner"/>
       </Item223>
       <Item224>
-        <Filename Value="..\..\Math\Raw\ClpNat256.pas"/>
-        <UnitName Value="ClpNat256"/>
+        <Filename Value="..\..\Interfaces\ClpIECSchnorrSipaSigner.pas"/>
+        <UnitName Value="ClpIECSchnorrSipaSigner"/>
       </Item224>
       <Item225>
-        <Filename Value="..\..\Math\Raw\ClpNat320.pas"/>
-        <UnitName Value="ClpNat320"/>
+        <Filename Value="..\..\Crypto\Signers\ClpECSchnorrSipaSigner.pas"/>
+        <UnitName Value="ClpECSchnorrSipaSigner"/>
       </Item225>
       <Item226>
-        <Filename Value="..\..\Crypto\Engines\ClpAesLightEngine.pas"/>
-        <UnitName Value="ClpAesLightEngine"/>
+        <Filename Value="..\..\Crypto\Signers\ClpSchnorrDigestSigner.pas"/>
+        <UnitName Value="ClpSchnorrDigestSigner"/>
       </Item226>
       <Item227>
-        <Filename Value="..\..\Interfaces\ClpIAesLightEngine.pas"/>
-        <UnitName Value="ClpIAesLightEngine"/>
+        <Filename Value="..\..\Interfaces\ClpISchnorr.pas"/>
+        <UnitName Value="ClpISchnorr"/>
       </Item227>
       <Item228>
-        <Filename Value="..\..\Crypto\EC\ClpCustomNamedCurves.pas"/>
-        <UnitName Value="ClpCustomNamedCurves"/>
+        <Filename Value="..\..\Interfaces\ClpISchnorrExt.pas"/>
+        <UnitName Value="ClpISchnorrExt"/>
       </Item228>
       <Item229>
-        <Filename Value="..\..\Math\Raw\ClpNat384.pas"/>
-        <UnitName Value="ClpNat384"/>
+        <Filename Value="..\..\Crypto\Engines\ClpBlowfishEngine.pas"/>
+        <UnitName Value="ClpBlowfishEngine"/>
       </Item229>
       <Item230>
-        <Filename Value="..\..\Math\Raw\ClpNat192.pas"/>
-        <UnitName Value="ClpNat192"/>
+        <Filename Value="..\..\Interfaces\ClpIBlowfishEngine.pas"/>
+        <UnitName Value="ClpIBlowfishEngine"/>
       </Item230>
       <Item231>
-        <Filename Value="..\..\Math\Raw\ClpNat512.pas"/>
-        <UnitName Value="ClpNat512"/>
+        <Filename Value="..\..\Math\EC\ClpECC.pas"/>
+        <UnitName Value="ClpECC"/>
       </Item231>
       <Item232>
-        <Filename Value="..\..\Math\Raw\ClpInterleave.pas"/>
-        <UnitName Value="ClpInterleave"/>
+        <Filename Value="..\..\Asn1\ClpAsn1Objects.pas"/>
+        <UnitName Value="ClpAsn1Objects"/>
       </Item232>
       <Item233>
-        <Filename Value="..\..\Asn1\Bsi\ClpBsiObjectIdentifiers.pas"/>
-        <UnitName Value="ClpBsiObjectIdentifiers"/>
+        <Filename Value="..\..\Crypto\Signers\SignersEncodings\ClpSignersEncodings.pas"/>
+        <UnitName Value="ClpSignersEncodings"/>
       </Item233>
       <Item234>
-        <Filename Value="..\..\Asn1\Eac\ClpEacObjectIdentifiers.pas"/>
-        <UnitName Value="ClpEacObjectIdentifiers"/>
+        <Filename Value="..\..\Interfaces\ClpISignersEncodings.pas"/>
+        <UnitName Value="ClpISignersEncodings"/>
       </Item234>
       <Item235>
-        <Filename Value="..\..\Interfaces\ClpIDsaExt.pas"/>
-        <UnitName Value="ClpIDsaExt"/>
+        <Filename Value="..\..\Utils\Encoders\ClpEncoders.pas"/>
+        <UnitName Value="ClpEncoders"/>
       </Item235>
       <Item236>
-        <Filename Value="..\..\Interfaces\ClpISchnorrDigestSigner.pas"/>
-        <UnitName Value="ClpISchnorrDigestSigner"/>
+        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecT283Custom.pas"/>
+        <UnitName Value="ClpSecT283Custom"/>
       </Item236>
       <Item237>
-        <Filename Value="..\..\Interfaces\ClpIECSchnorrSipaSigner.pas"/>
-        <UnitName Value="ClpIECSchnorrSipaSigner"/>
+        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP521R1Custom.pas"/>
+        <UnitName Value="ClpSecP521R1Custom"/>
       </Item237>
       <Item238>
-        <Filename Value="..\..\Crypto\Signers\ClpECSchnorrSipaSigner.pas"/>
-        <UnitName Value="ClpECSchnorrSipaSigner"/>
+        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP384R1Custom.pas"/>
+        <UnitName Value="ClpSecP384R1Custom"/>
       </Item238>
       <Item239>
-        <Filename Value="..\..\Crypto\Signers\ClpSchnorrDigestSigner.pas"/>
-        <UnitName Value="ClpSchnorrDigestSigner"/>
+        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP256R1Custom.pas"/>
+        <UnitName Value="ClpSecP256R1Custom"/>
       </Item239>
       <Item240>
-        <Filename Value="..\..\Interfaces\ClpISchnorr.pas"/>
-        <UnitName Value="ClpISchnorr"/>
+        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas"/>
+        <UnitName Value="ClpSecP256K1Custom"/>
       </Item240>
       <Item241>
-        <Filename Value="..\..\Interfaces\ClpISchnorrExt.pas"/>
-        <UnitName Value="ClpISchnorrExt"/>
+        <Filename Value="..\..\Interfaces\ClpIX9ECC.pas"/>
+        <UnitName Value="ClpIX9ECC"/>
       </Item241>
       <Item242>
-        <Filename Value="..\..\Crypto\Engines\ClpBlowfishEngine.pas"/>
-        <UnitName Value="ClpBlowfishEngine"/>
+        <Filename Value="..\..\Asn1\X9\ClpX9ECC.pas"/>
+        <UnitName Value="ClpX9ECC"/>
       </Item242>
       <Item243>
-        <Filename Value="..\..\Interfaces\ClpIBlowfishEngine.pas"/>
-        <UnitName Value="ClpIBlowfishEngine"/>
+        <Filename Value="..\..\Interfaces\ClpIAsn1Objects.pas"/>
+        <UnitName Value="ClpIAsn1Objects"/>
       </Item243>
       <Item244>
-        <Filename Value="..\..\Math\EC\ClpECC.pas"/>
-        <UnitName Value="ClpECC"/>
+        <Filename Value="..\..\Crypto\Modes\ClpBlockCipherModes.pas"/>
+        <UnitName Value="ClpBlockCipherModes"/>
       </Item244>
       <Item245>
-        <Filename Value="..\..\Asn1\ClpAsn1Objects.pas"/>
-        <UnitName Value="ClpAsn1Objects"/>
+        <Filename Value="..\..\Math\EC\ClpECCurveConstants.pas"/>
+        <UnitName Value="ClpECCurveConstants"/>
       </Item245>
       <Item246>
-        <Filename Value="..\..\Crypto\Signers\SignersEncodings\ClpSignersEncodings.pas"/>
-        <UnitName Value="ClpSignersEncodings"/>
+        <Filename Value="..\..\Interfaces\ClpIBlockCipherModes.pas"/>
+        <UnitName Value="ClpIBlockCipherModes"/>
       </Item246>
       <Item247>
-        <Filename Value="..\..\Interfaces\ClpISignersEncodings.pas"/>
-        <UnitName Value="ClpISignersEncodings"/>
+        <Filename Value="..\..\Interfaces\ClpIPaddingModes.pas"/>
+        <UnitName Value="ClpIPaddingModes"/>
       </Item247>
       <Item248>
-        <Filename Value="..\..\Utils\Encoders\ClpEncoders.pas"/>
-        <UnitName Value="ClpEncoders"/>
+        <Filename Value="..\..\Interfaces\ClpISecP256K1Custom.pas"/>
+        <UnitName Value="ClpISecP256K1Custom"/>
       </Item248>
       <Item249>
-        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecT283Custom.pas"/>
-        <UnitName Value="ClpSecT283Custom"/>
+        <Filename Value="..\..\Interfaces\ClpISecP256R1Custom.pas"/>
+        <UnitName Value="ClpISecP256R1Custom"/>
       </Item249>
       <Item250>
-        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP521R1Custom.pas"/>
-        <UnitName Value="ClpSecP521R1Custom"/>
+        <Filename Value="..\..\Interfaces\ClpISecP384R1Custom.pas"/>
+        <UnitName Value="ClpISecP384R1Custom"/>
       </Item250>
       <Item251>
-        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP384R1Custom.pas"/>
-        <UnitName Value="ClpSecP384R1Custom"/>
+        <Filename Value="..\..\Interfaces\ClpISecP521R1Custom.pas"/>
+        <UnitName Value="ClpISecP521R1Custom"/>
       </Item251>
       <Item252>
-        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP256R1Custom.pas"/>
-        <UnitName Value="ClpSecP256R1Custom"/>
+        <Filename Value="..\..\Interfaces\ClpISecT283Custom.pas"/>
+        <UnitName Value="ClpISecT283Custom"/>
       </Item252>
       <Item253>
-        <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas"/>
-        <UnitName Value="ClpSecP256K1Custom"/>
+        <Filename Value="..\..\Crypto\Paddings\ClpPaddingModes.pas"/>
+        <UnitName Value="ClpPaddingModes"/>
       </Item253>
       <Item254>
-        <Filename Value="..\..\Interfaces\ClpIX9ECC.pas"/>
-        <UnitName Value="ClpIX9ECC"/>
+        <Filename Value="..\..\Interfaces\ClpIECC.pas"/>
+        <UnitName Value="ClpIECC"/>
       </Item254>
       <Item255>
-        <Filename Value="..\..\Asn1\X9\ClpX9ECC.pas"/>
-        <UnitName Value="ClpX9ECC"/>
+        <Filename Value="..\..\Interfaces\ClpISpeckEngine.pas"/>
+        <UnitName Value="ClpISpeckEngine"/>
       </Item255>
       <Item256>
-        <Filename Value="..\..\Interfaces\ClpIAsn1Objects.pas"/>
-        <UnitName Value="ClpIAsn1Objects"/>
+        <Filename Value="..\..\Crypto\Engines\ClpSpeckEngine.pas"/>
+        <UnitName Value="ClpSpeckEngine"/>
       </Item256>
       <Item257>
-        <Filename Value="..\..\Crypto\Modes\ClpBlockCipherModes.pas"/>
-        <UnitName Value="ClpBlockCipherModes"/>
+        <Filename Value="..\..\Interfaces\ClpIBufferedStreamCipher.pas"/>
+        <UnitName Value="ClpIBufferedStreamCipher"/>
       </Item257>
       <Item258>
-        <Filename Value="..\..\Math\EC\ClpECCurveConstants.pas"/>
-        <UnitName Value="ClpECCurveConstants"/>
+        <Filename Value="..\..\Interfaces\ClpIChaChaEngine.pas"/>
+        <UnitName Value="ClpIChaChaEngine"/>
       </Item258>
       <Item259>
-        <Filename Value="..\..\Interfaces\ClpIBlockCipherModes.pas"/>
-        <UnitName Value="ClpIBlockCipherModes"/>
+        <Filename Value="..\..\Interfaces\ClpIXSalsa20Engine.pas"/>
+        <UnitName Value="ClpIXSalsa20Engine"/>
       </Item259>
       <Item260>
-        <Filename Value="..\..\Interfaces\ClpIPaddingModes.pas"/>
-        <UnitName Value="ClpIPaddingModes"/>
+        <Filename Value="..\..\Interfaces\ClpISalsa20Engine.pas"/>
+        <UnitName Value="ClpISalsa20Engine"/>
       </Item260>
       <Item261>
-        <Filename Value="..\..\Interfaces\ClpISecP256K1Custom.pas"/>
-        <UnitName Value="ClpISecP256K1Custom"/>
+        <Filename Value="..\..\Crypto\ClpBufferedStreamCipher.pas"/>
+        <UnitName Value="ClpBufferedStreamCipher"/>
       </Item261>
       <Item262>
-        <Filename Value="..\..\Interfaces\ClpISecP256R1Custom.pas"/>
-        <UnitName Value="ClpISecP256R1Custom"/>
+        <Filename Value="..\..\Crypto\Engines\ClpSalsa20Engine.pas"/>
+        <UnitName Value="ClpSalsa20Engine"/>
       </Item262>
       <Item263>
-        <Filename Value="..\..\Interfaces\ClpISecP384R1Custom.pas"/>
-        <UnitName Value="ClpISecP384R1Custom"/>
+        <Filename Value="..\..\Crypto\Engines\ClpXSalsa20Engine.pas"/>
+        <UnitName Value="ClpXSalsa20Engine"/>
       </Item263>
       <Item264>
-        <Filename Value="..\..\Interfaces\ClpISecP521R1Custom.pas"/>
-        <UnitName Value="ClpISecP521R1Custom"/>
+        <Filename Value="..\..\Crypto\Engines\ClpChaChaEngine.pas"/>
+        <UnitName Value="ClpChaChaEngine"/>
       </Item264>
       <Item265>
-        <Filename Value="..\..\Interfaces\ClpISecT283Custom.pas"/>
-        <UnitName Value="ClpISecT283Custom"/>
+        <Filename Value="..\..\Interfaces\ClpIRijndaelEngine.pas"/>
+        <UnitName Value="ClpIRijndaelEngine"/>
       </Item265>
       <Item266>
-        <Filename Value="..\..\Crypto\Paddings\ClpPaddingModes.pas"/>
-        <UnitName Value="ClpPaddingModes"/>
+        <Filename Value="..\..\Crypto\Engines\ClpRijndaelEngine.pas"/>
+        <UnitName Value="ClpRijndaelEngine"/>
       </Item266>
       <Item267>
-        <Filename Value="..\..\Interfaces\ClpIECC.pas"/>
-        <UnitName Value="ClpIECC"/>
+        <Filename Value="..\..\Interfaces\ClpIIESParameterSpec.pas"/>
+        <UnitName Value="ClpIIESParameterSpec"/>
       </Item267>
       <Item268>
-        <Filename Value="..\..\Interfaces\ClpISpeckEngine.pas"/>
-        <UnitName Value="ClpISpeckEngine"/>
+        <Filename Value="..\..\Interfaces\ClpIAlgorithmParameterSpec.pas"/>
+        <UnitName Value="ClpIAlgorithmParameterSpec"/>
       </Item268>
       <Item269>
-        <Filename Value="..\..\Crypto\Engines\ClpSpeckEngine.pas"/>
-        <UnitName Value="ClpSpeckEngine"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpIESParameterSpec.pas"/>
+        <UnitName Value="ClpIESParameterSpec"/>
       </Item269>
       <Item270>
-        <Filename Value="..\..\Interfaces\ClpIBufferedStreamCipher.pas"/>
-        <UnitName Value="ClpIBufferedStreamCipher"/>
+        <Filename Value="..\..\Math\EC\Custom\Djb\ClpCurve25519Custom.pas"/>
+        <UnitName Value="ClpCurve25519Custom"/>
       </Item270>
       <Item271>
-        <Filename Value="..\..\Interfaces\ClpIChaChaEngine.pas"/>
-        <UnitName Value="ClpIChaChaEngine"/>
+        <Filename Value="..\..\Interfaces\ClpICurve25519Custom.pas"/>
+        <UnitName Value="ClpICurve25519Custom"/>
       </Item271>
       <Item272>
-        <Filename Value="..\..\Interfaces\ClpIXSalsa20Engine.pas"/>
-        <UnitName Value="ClpIXSalsa20Engine"/>
+        <Filename Value="..\..\Crypto\Engines\ClpSpeckLegacyEngine.pas"/>
+        <UnitName Value="ClpSpeckLegacyEngine"/>
       </Item272>
       <Item273>
-        <Filename Value="..\..\Interfaces\ClpISalsa20Engine.pas"/>
-        <UnitName Value="ClpISalsa20Engine"/>
+        <Filename Value="..\..\Interfaces\ClpISpeckLegacyEngine.pas"/>
+        <UnitName Value="ClpISpeckLegacyEngine"/>
       </Item273>
       <Item274>
-        <Filename Value="..\..\Crypto\ClpBufferedStreamCipher.pas"/>
-        <UnitName Value="ClpBufferedStreamCipher"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519.pas"/>
+        <UnitName Value="ClpIEd25519"/>
       </Item274>
       <Item275>
-        <Filename Value="..\..\Crypto\Engines\ClpSalsa20Engine.pas"/>
-        <UnitName Value="ClpSalsa20Engine"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2B.pas"/>
+        <UnitName Value="ClpIEd25519Blake2B"/>
       </Item275>
       <Item276>
-        <Filename Value="..\..\Crypto\Engines\ClpXSalsa20Engine.pas"/>
-        <UnitName Value="ClpXSalsa20Engine"/>
+        <Filename Value="..\..\Math\EC\Rfc7748\ClpX25519Field.pas"/>
+        <UnitName Value="ClpX25519Field"/>
       </Item276>
       <Item277>
-        <Filename Value="..\..\Crypto\Engines\ClpChaChaEngine.pas"/>
-        <UnitName Value="ClpChaChaEngine"/>
+        <Filename Value="..\..\Math\EC\Rfc8032\ClpEd25519.pas"/>
+        <UnitName Value="ClpEd25519"/>
       </Item277>
       <Item278>
-        <Filename Value="..\..\Interfaces\ClpIRijndaelEngine.pas"/>
-        <UnitName Value="ClpIRijndaelEngine"/>
+        <Filename Value="..\..\Math\EC\Rfc8032\ClpEd25519Blake2B.pas"/>
+        <UnitName Value="ClpEd25519Blake2B"/>
       </Item278>
       <Item279>
-        <Filename Value="..\..\Crypto\Engines\ClpRijndaelEngine.pas"/>
-        <UnitName Value="ClpRijndaelEngine"/>
+        <Filename Value="..\..\Math\EC\Rfc7748\ClpX25519.pas"/>
+        <UnitName Value="ClpX25519"/>
       </Item279>
       <Item280>
-        <Filename Value="..\..\Interfaces\ClpIIESParameterSpec.pas"/>
-        <UnitName Value="ClpIIESParameterSpec"/>
+        <Filename Value="..\..\Asn1\Edec\ClpEdECObjectIdentifiers.pas"/>
+        <UnitName Value="ClpEdECObjectIdentifiers"/>
       </Item280>
       <Item281>
-        <Filename Value="..\..\Interfaces\ClpIAlgorithmParameterSpec.pas"/>
-        <UnitName Value="ClpIAlgorithmParameterSpec"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519CtxBlake2BSigner.pas"/>
+        <UnitName Value="ClpIEd25519CtxBlake2BSigner"/>
       </Item281>
       <Item282>
-        <Filename Value="..\..\Crypto\Parameters\ClpIESParameterSpec.pas"/>
-        <UnitName Value="ClpIESParameterSpec"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519PhBlake2BSigner.pas"/>
+        <UnitName Value="ClpIEd25519PhBlake2BSigner"/>
       </Item282>
       <Item283>
-        <Filename Value="..\..\Math\EC\Custom\Djb\ClpCurve25519Custom.pas"/>
-        <UnitName Value="ClpCurve25519Custom"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519PhSigner.pas"/>
+        <UnitName Value="ClpIEd25519PhSigner"/>
       </Item283>
       <Item284>
-        <Filename Value="..\..\Interfaces\ClpICurve25519Custom.pas"/>
-        <UnitName Value="ClpICurve25519Custom"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519CtxSigner.pas"/>
+        <UnitName Value="ClpIEd25519CtxSigner"/>
       </Item284>
       <Item285>
-        <Filename Value="..\..\Crypto\Engines\ClpSpeckLegacyEngine.pas"/>
-        <UnitName Value="ClpSpeckLegacyEngine"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BSigner.pas"/>
+        <UnitName Value="ClpIEd25519Blake2BSigner"/>
       </Item285>
       <Item286>
-        <Filename Value="..\..\Interfaces\ClpISpeckLegacyEngine.pas"/>
-        <UnitName Value="ClpISpeckLegacyEngine"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519Signer.pas"/>
+        <UnitName Value="ClpIEd25519Signer"/>
       </Item286>
       <Item287>
-        <Filename Value="..\..\Interfaces\ClpIEd25519.pas"/>
-        <UnitName Value="ClpIEd25519"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpIEd25519Blake2BKeyGenerationParameters"/>
       </Item287>
       <Item288>
-        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2B.pas"/>
-        <UnitName Value="ClpIEd25519Blake2B"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519KeyGenerationParameters.pas"/>
+        <UnitName Value="ClpIEd25519KeyGenerationParameters"/>
       </Item288>
       <Item289>
-        <Filename Value="..\..\Math\EC\Rfc7748\ClpX25519Field.pas"/>
-        <UnitName Value="ClpX25519Field"/>
+        <Filename Value="..\..\Interfaces\ClpIX25519KeyGenerationParameters.pas"/>
+        <UnitName Value="ClpIX25519KeyGenerationParameters"/>
       </Item289>
       <Item290>
-        <Filename Value="..\..\Math\EC\Rfc8032\ClpEd25519.pas"/>
-        <UnitName Value="ClpEd25519"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIEd25519Blake2BKeyPairGenerator"/>
       </Item290>
       <Item291>
-        <Filename Value="..\..\Math\EC\Rfc8032\ClpEd25519Blake2B.pas"/>
-        <UnitName Value="ClpEd25519Blake2B"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519KeyPairGenerator.pas"/>
+        <UnitName Value="ClpIEd25519KeyPairGenerator"/>
       </Item291>
       <Item292>
-        <Filename Value="..\..\Math\EC\Rfc7748\ClpX25519.pas"/>
-        <UnitName Value="ClpX25519"/>
+        <Filename Value="..\..\Interfaces\ClpIX25519KeyPairGenerator.pas"/>
+        <UnitName Value="ClpIX25519KeyPairGenerator"/>
       </Item292>
       <Item293>
-        <Filename Value="..\..\Asn1\Edec\ClpEdECObjectIdentifiers.pas"/>
-        <UnitName Value="ClpEdECObjectIdentifiers"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpIEd25519Blake2BPrivateKeyParameters"/>
       </Item293>
       <Item294>
-        <Filename Value="..\..\Interfaces\ClpIEd25519CtxBlake2BSigner.pas"/>
-        <UnitName Value="ClpIEd25519CtxBlake2BSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BPublicKeyParameters.pas"/>
+        <UnitName Value="ClpIEd25519Blake2BPublicKeyParameters"/>
       </Item294>
       <Item295>
-        <Filename Value="..\..\Interfaces\ClpIEd25519PhBlake2BSigner.pas"/>
-        <UnitName Value="ClpIEd25519PhBlake2BSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519PrivateKeyParameters.pas"/>
+        <UnitName Value="ClpIEd25519PrivateKeyParameters"/>
       </Item295>
       <Item296>
-        <Filename Value="..\..\Interfaces\ClpIEd25519PhSigner.pas"/>
-        <UnitName Value="ClpIEd25519PhSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIEd25519PublicKeyParameters.pas"/>
+        <UnitName Value="ClpIEd25519PublicKeyParameters"/>
       </Item296>
       <Item297>
-        <Filename Value="..\..\Interfaces\ClpIEd25519CtxSigner.pas"/>
-        <UnitName Value="ClpIEd25519CtxSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIX25519PublicKeyParameters.pas"/>
+        <UnitName Value="ClpIX25519PublicKeyParameters"/>
       </Item297>
       <Item298>
-        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BSigner.pas"/>
-        <UnitName Value="ClpIEd25519Blake2BSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIX25519PrivateKeyParameters.pas"/>
+        <UnitName Value="ClpIX25519PrivateKeyParameters"/>
       </Item298>
       <Item299>
-        <Filename Value="..\..\Interfaces\ClpIEd25519Signer.pas"/>
-        <UnitName Value="ClpIEd25519Signer"/>
+        <Filename Value="..\..\Interfaces\ClpIX25519Agreement.pas"/>
+        <UnitName Value="ClpIX25519Agreement"/>
       </Item299>
       <Item300>
-        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BKeyGenerationParameters.pas"/>
-        <UnitName Value="ClpIEd25519Blake2BKeyGenerationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIRawAgreement.pas"/>
+        <UnitName Value="ClpIRawAgreement"/>
       </Item300>
       <Item301>
-        <Filename Value="..\..\Interfaces\ClpIEd25519KeyGenerationParameters.pas"/>
-        <UnitName Value="ClpIEd25519KeyGenerationParameters"/>
+        <Filename Value="..\..\Crypto\Agreement\ClpX25519Agreement.pas"/>
+        <UnitName Value="ClpX25519Agreement"/>
       </Item301>
       <Item302>
-        <Filename Value="..\..\Interfaces\ClpIX25519KeyGenerationParameters.pas"/>
-        <UnitName Value="ClpIX25519KeyGenerationParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpEd25519Blake2BKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpEd25519Blake2BKeyGenerationParameters"/>
       </Item302>
       <Item303>
-        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BKeyPairGenerator.pas"/>
-        <UnitName Value="ClpIEd25519Blake2BKeyPairGenerator"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpEd25519KeyGenerationParameters.pas"/>
+        <UnitName Value="ClpEd25519KeyGenerationParameters"/>
       </Item303>
       <Item304>
-        <Filename Value="..\..\Interfaces\ClpIEd25519KeyPairGenerator.pas"/>
-        <UnitName Value="ClpIEd25519KeyPairGenerator"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpX25519KeyGenerationParameters.pas"/>
+        <UnitName Value="ClpX25519KeyGenerationParameters"/>
       </Item304>
       <Item305>
-        <Filename Value="..\..\Interfaces\ClpIX25519KeyPairGenerator.pas"/>
-        <UnitName Value="ClpIX25519KeyPairGenerator"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpEd25519Blake2BPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpEd25519Blake2BPrivateKeyParameters"/>
       </Item305>
       <Item306>
-        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BPrivateKeyParameters.pas"/>
-        <UnitName Value="ClpIEd25519Blake2BPrivateKeyParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpEd25519Blake2BPublicKeyParameters.pas"/>
+        <UnitName Value="ClpEd25519Blake2BPublicKeyParameters"/>
       </Item306>
       <Item307>
-        <Filename Value="..\..\Interfaces\ClpIEd25519Blake2BPublicKeyParameters.pas"/>
-        <UnitName Value="ClpIEd25519Blake2BPublicKeyParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpEd25519PublicKeyParameters.pas"/>
+        <UnitName Value="ClpEd25519PublicKeyParameters"/>
       </Item307>
       <Item308>
-        <Filename Value="..\..\Interfaces\ClpIEd25519PrivateKeyParameters.pas"/>
-        <UnitName Value="ClpIEd25519PrivateKeyParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpEd25519PrivateKeyParameters.pas"/>
+        <UnitName Value="ClpEd25519PrivateKeyParameters"/>
       </Item308>
       <Item309>
-        <Filename Value="..\..\Interfaces\ClpIEd25519PublicKeyParameters.pas"/>
-        <UnitName Value="ClpIEd25519PublicKeyParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpX25519PublicKeyParameters.pas"/>
+        <UnitName Value="ClpX25519PublicKeyParameters"/>
       </Item309>
       <Item310>
-        <Filename Value="..\..\Interfaces\ClpIX25519PublicKeyParameters.pas"/>
-        <UnitName Value="ClpIX25519PublicKeyParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpX25519PrivateKeyParameters.pas"/>
+        <UnitName Value="ClpX25519PrivateKeyParameters"/>
       </Item310>
       <Item311>
-        <Filename Value="..\..\Interfaces\ClpIX25519PrivateKeyParameters.pas"/>
-        <UnitName Value="ClpIX25519PrivateKeyParameters"/>
+        <Filename Value="..\..\Crypto\Generators\ClpEd25519Blake2BKeyPairGenerator.pas"/>
+        <UnitName Value="ClpEd25519Blake2BKeyPairGenerator"/>
       </Item311>
       <Item312>
-        <Filename Value="..\..\Interfaces\ClpIX25519Agreement.pas"/>
-        <UnitName Value="ClpIX25519Agreement"/>
+        <Filename Value="..\..\Crypto\Generators\ClpEd25519KeyPairGenerator.pas"/>
+        <UnitName Value="ClpEd25519KeyPairGenerator"/>
       </Item312>
       <Item313>
-        <Filename Value="..\..\Interfaces\ClpIRawAgreement.pas"/>
-        <UnitName Value="ClpIRawAgreement"/>
+        <Filename Value="..\..\Crypto\Generators\ClpX25519KeyPairGenerator.pas"/>
+        <UnitName Value="ClpX25519KeyPairGenerator"/>
       </Item313>
       <Item314>
-        <Filename Value="..\..\Crypto\Agreement\ClpX25519Agreement.pas"/>
-        <UnitName Value="ClpX25519Agreement"/>
+        <Filename Value="..\..\Crypto\Signers\ClpEd25519PhBlake2BSigner.pas"/>
+        <UnitName Value="ClpEd25519PhBlake2BSigner"/>
       </Item314>
       <Item315>
-        <Filename Value="..\..\Crypto\Parameters\ClpEd25519Blake2BKeyGenerationParameters.pas"/>
-        <UnitName Value="ClpEd25519Blake2BKeyGenerationParameters"/>
+        <Filename Value="..\..\Crypto\Signers\ClpEd25519PhSigner.pas"/>
+        <UnitName Value="ClpEd25519PhSigner"/>
       </Item315>
       <Item316>
-        <Filename Value="..\..\Crypto\Parameters\ClpEd25519KeyGenerationParameters.pas"/>
-        <UnitName Value="ClpEd25519KeyGenerationParameters"/>
+        <Filename Value="..\..\Crypto\Signers\ClpEd25519Signer.pas"/>
+        <UnitName Value="ClpEd25519Signer"/>
       </Item316>
       <Item317>
-        <Filename Value="..\..\Crypto\Parameters\ClpX25519KeyGenerationParameters.pas"/>
-        <UnitName Value="ClpX25519KeyGenerationParameters"/>
+        <Filename Value="..\..\Crypto\Signers\ClpEd25519CtxBlake2BSigner.pas"/>
+        <UnitName Value="ClpEd25519CtxBlake2BSigner"/>
       </Item317>
       <Item318>
-        <Filename Value="..\..\Crypto\Parameters\ClpEd25519Blake2BPrivateKeyParameters.pas"/>
-        <UnitName Value="ClpEd25519Blake2BPrivateKeyParameters"/>
+        <Filename Value="..\..\Crypto\Signers\ClpEd25519CtxSigner.pas"/>
+        <UnitName Value="ClpEd25519CtxSigner"/>
       </Item318>
       <Item319>
-        <Filename Value="..\..\Crypto\Parameters\ClpEd25519Blake2BPublicKeyParameters.pas"/>
-        <UnitName Value="ClpEd25519Blake2BPublicKeyParameters"/>
+        <Filename Value="..\..\Crypto\Signers\ClpEd25519Blake2BSigner.pas"/>
+        <UnitName Value="ClpEd25519Blake2BSigner"/>
       </Item319>
       <Item320>
-        <Filename Value="..\..\Crypto\Parameters\ClpEd25519PublicKeyParameters.pas"/>
-        <UnitName Value="ClpEd25519PublicKeyParameters"/>
+        <Filename Value="..\..\Asn1\TeleTrust\ClpTeleTrusTNamedCurves.pas"/>
+        <UnitName Value="ClpTeleTrusTNamedCurves"/>
       </Item320>
       <Item321>
-        <Filename Value="..\..\Crypto\Parameters\ClpEd25519PrivateKeyParameters.pas"/>
-        <UnitName Value="ClpEd25519PrivateKeyParameters"/>
+        <Filename Value="..\..\Security\ClpAgreementUtilities.pas"/>
+        <UnitName Value="ClpAgreementUtilities"/>
       </Item321>
       <Item322>
-        <Filename Value="..\..\Crypto\Parameters\ClpX25519PublicKeyParameters.pas"/>
-        <UnitName Value="ClpX25519PublicKeyParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIKdf1BytesGenerator.pas"/>
+        <UnitName Value="ClpIKdf1BytesGenerator"/>
       </Item322>
       <Item323>
-        <Filename Value="..\..\Crypto\Parameters\ClpX25519PrivateKeyParameters.pas"/>
-        <UnitName Value="ClpX25519PrivateKeyParameters"/>
+        <Filename Value="..\..\Crypto\Generators\ClpKdf1BytesGenerator.pas"/>
+        <UnitName Value="ClpKdf1BytesGenerator"/>
       </Item323>
       <Item324>
-        <Filename Value="..\..\Crypto\Generators\ClpEd25519Blake2BKeyPairGenerator.pas"/>
-        <UnitName Value="ClpEd25519Blake2BKeyPairGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIArgon2ParametersGenerator.pas"/>
+        <UnitName Value="ClpIArgon2ParametersGenerator"/>
       </Item324>
       <Item325>
-        <Filename Value="..\..\Crypto\Generators\ClpEd25519KeyPairGenerator.pas"/>
-        <UnitName Value="ClpEd25519KeyPairGenerator"/>
+        <Filename Value="..\..\Crypto\Generators\ClpArgon2ParametersGenerator.pas"/>
+        <UnitName Value="ClpArgon2ParametersGenerator"/>
       </Item325>
       <Item326>
-        <Filename Value="..\..\Crypto\Generators\ClpX25519KeyPairGenerator.pas"/>
-        <UnitName Value="ClpX25519KeyPairGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIScryptParametersGenerator.pas"/>
+        <UnitName Value="ClpIScryptParametersGenerator"/>
       </Item326>
       <Item327>
-        <Filename Value="..\..\Crypto\Signers\ClpEd25519PhBlake2BSigner.pas"/>
-        <UnitName Value="ClpEd25519PhBlake2BSigner"/>
+        <Filename Value="..\..\Crypto\Generators\ClpScryptParametersGenerator.pas"/>
+        <UnitName Value="ClpScryptParametersGenerator"/>
       </Item327>
       <Item328>
-        <Filename Value="..\..\Crypto\Signers\ClpEd25519PhSigner.pas"/>
-        <UnitName Value="ClpEd25519PhSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIDHAgreement.pas"/>
+        <UnitName Value="ClpIDHAgreement"/>
       </Item328>
       <Item329>
-        <Filename Value="..\..\Crypto\Signers\ClpEd25519Signer.pas"/>
-        <UnitName Value="ClpEd25519Signer"/>
+        <Filename Value="..\..\Interfaces\ClpIDHBasicAgreement.pas"/>
+        <UnitName Value="ClpIDHBasicAgreement"/>
       </Item329>
       <Item330>
-        <Filename Value="..\..\Crypto\Signers\ClpEd25519CtxBlake2BSigner.pas"/>
-        <UnitName Value="ClpEd25519CtxBlake2BSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIDHBasicKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIDHBasicKeyPairGenerator"/>
       </Item330>
       <Item331>
-        <Filename Value="..\..\Crypto\Signers\ClpEd25519CtxSigner.pas"/>
-        <UnitName Value="ClpEd25519CtxSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIDHKeyPairGenerator"/>
       </Item331>
       <Item332>
-        <Filename Value="..\..\Crypto\Signers\ClpEd25519Blake2BSigner.pas"/>
-        <UnitName Value="ClpEd25519Blake2BSigner"/>
+        <Filename Value="..\..\Interfaces\ClpIDHPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpIDHPrivateKeyParameters"/>
       </Item332>
       <Item333>
-        <Filename Value="..\..\Asn1\TeleTrust\ClpTeleTrusTNamedCurves.pas"/>
-        <UnitName Value="ClpTeleTrusTNamedCurves"/>
+        <Filename Value="..\..\Interfaces\ClpIDHPublicKeyParameters.pas"/>
+        <UnitName Value="ClpIDHPublicKeyParameters"/>
       </Item333>
       <Item334>
-        <Filename Value="..\..\Security\ClpAgreementUtilities.pas"/>
-        <UnitName Value="ClpAgreementUtilities"/>
+        <Filename Value="..\..\Interfaces\ClpIDHParametersGenerator.pas"/>
+        <UnitName Value="ClpIDHParametersGenerator"/>
       </Item334>
       <Item335>
-        <Filename Value="..\..\Interfaces\ClpIKdf1BytesGenerator.pas"/>
-        <UnitName Value="ClpIKdf1BytesGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpIDHKeyGenerationParameters"/>
       </Item335>
       <Item336>
-        <Filename Value="..\..\Crypto\Generators\ClpKdf1BytesGenerator.pas"/>
-        <UnitName Value="ClpKdf1BytesGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDHParameters.pas"/>
+        <UnitName Value="ClpIDHParameters"/>
       </Item336>
       <Item337>
-        <Filename Value="..\..\Interfaces\ClpIArgon2ParametersGenerator.pas"/>
-        <UnitName Value="ClpIArgon2ParametersGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyGeneratorHelper.pas"/>
+        <UnitName Value="ClpIDHKeyGeneratorHelper"/>
       </Item337>
       <Item338>
-        <Filename Value="..\..\Crypto\Generators\ClpArgon2ParametersGenerator.pas"/>
-        <UnitName Value="ClpArgon2ParametersGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyParameters.pas"/>
+        <UnitName Value="ClpIDHKeyParameters"/>
       </Item338>
       <Item339>
-        <Filename Value="..\..\Interfaces\ClpIScryptParametersGenerator.pas"/>
-        <UnitName Value="ClpIScryptParametersGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDHValidationParameters.pas"/>
+        <UnitName Value="ClpIDHValidationParameters"/>
       </Item339>
       <Item340>
-        <Filename Value="..\..\Crypto\Generators\ClpScryptParametersGenerator.pas"/>
-        <UnitName Value="ClpScryptParametersGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIDHDomainParameters.pas"/>
+        <UnitName Value="ClpIDHDomainParameters"/>
       </Item340>
       <Item341>
-        <Filename Value="..\..\Interfaces\ClpIDHAgreement.pas"/>
-        <UnitName Value="ClpIDHAgreement"/>
+        <Filename Value="..\..\Interfaces\ClpIDHValidationParams.pas"/>
+        <UnitName Value="ClpIDHValidationParams"/>
       </Item341>
       <Item342>
-        <Filename Value="..\..\Interfaces\ClpIDHBasicAgreement.pas"/>
-        <UnitName Value="ClpIDHBasicAgreement"/>
+        <Filename Value="..\..\Crypto\Agreement\ClpDHAgreement.pas"/>
+        <UnitName Value="ClpDHAgreement"/>
       </Item342>
       <Item343>
-        <Filename Value="..\..\Interfaces\ClpIDHBasicKeyPairGenerator.pas"/>
-        <UnitName Value="ClpIDHBasicKeyPairGenerator"/>
+        <Filename Value="..\..\Crypto\Agreement\ClpDHBasicAgreement.pas"/>
+        <UnitName Value="ClpDHBasicAgreement"/>
       </Item343>
       <Item344>
-        <Filename Value="..\..\Interfaces\ClpIDHKeyPairGenerator.pas"/>
-        <UnitName Value="ClpIDHKeyPairGenerator"/>
+        <Filename Value="..\..\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas"/>
+        <UnitName Value="ClpDHBasicKeyPairGenerator"/>
       </Item344>
       <Item345>
-        <Filename Value="..\..\Interfaces\ClpIDHPrivateKeyParameters.pas"/>
-        <UnitName Value="ClpIDHPrivateKeyParameters"/>
+        <Filename Value="..\..\Crypto\Generators\ClpDHKeyPairGenerator.pas"/>
+        <UnitName Value="ClpDHKeyPairGenerator"/>
       </Item345>
       <Item346>
-        <Filename Value="..\..\Interfaces\ClpIDHPublicKeyParameters.pas"/>
-        <UnitName Value="ClpIDHPublicKeyParameters"/>
+        <Filename Value="..\..\Crypto\Generators\ClpDHParametersGenerator.pas"/>
+        <UnitName Value="ClpDHParametersGenerator"/>
       </Item346>
       <Item347>
-        <Filename Value="..\..\Interfaces\ClpIDHParametersGenerator.pas"/>
-        <UnitName Value="ClpIDHParametersGenerator"/>
+        <Filename Value="..\..\Crypto\Generators\ClpDHKeyGeneratorHelper.pas"/>
+        <UnitName Value="ClpDHKeyGeneratorHelper"/>
       </Item347>
       <Item348>
-        <Filename Value="..\..\Interfaces\ClpIDHKeyGenerationParameters.pas"/>
-        <UnitName Value="ClpIDHKeyGenerationParameters"/>
+        <Filename Value="..\..\Crypto\Generators\ClpDHParametersHelper.pas"/>
+        <UnitName Value="ClpDHParametersHelper"/>
       </Item348>
       <Item349>
-        <Filename Value="..\..\Interfaces\ClpIDHParameters.pas"/>
-        <UnitName Value="ClpIDHParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpDHPrivateKeyParameters"/>
       </Item349>
       <Item350>
-        <Filename Value="..\..\Interfaces\ClpIDHKeyGeneratorHelper.pas"/>
-        <UnitName Value="ClpIDHKeyGeneratorHelper"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHPublicKeyParameters.pas"/>
+        <UnitName Value="ClpDHPublicKeyParameters"/>
       </Item350>
       <Item351>
-        <Filename Value="..\..\Interfaces\ClpIDHKeyParameters.pas"/>
-        <UnitName Value="ClpIDHKeyParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpDHKeyGenerationParameters"/>
       </Item351>
       <Item352>
-        <Filename Value="..\..\Interfaces\ClpIDHValidationParameters.pas"/>
-        <UnitName Value="ClpIDHValidationParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHKeyParameters.pas"/>
+        <UnitName Value="ClpDHKeyParameters"/>
       </Item352>
       <Item353>
-        <Filename Value="..\..\Interfaces\ClpIDHDomainParameters.pas"/>
-        <UnitName Value="ClpIDHDomainParameters"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHValidationParameters.pas"/>
+        <UnitName Value="ClpDHValidationParameters"/>
       </Item353>
       <Item354>
-        <Filename Value="..\..\Interfaces\ClpIDHValidationParams.pas"/>
-        <UnitName Value="ClpIDHValidationParams"/>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHParameters.pas"/>
+        <UnitName Value="ClpDHParameters"/>
       </Item354>
       <Item355>
-        <Filename Value="..\..\Crypto\Agreement\ClpDHAgreement.pas"/>
-        <UnitName Value="ClpDHAgreement"/>
+        <Filename Value="..\..\Asn1\X9\ClpDHDomainParameters.pas"/>
+        <UnitName Value="ClpDHDomainParameters"/>
       </Item355>
       <Item356>
-        <Filename Value="..\..\Crypto\Agreement\ClpDHBasicAgreement.pas"/>
-        <UnitName Value="ClpDHBasicAgreement"/>
+        <Filename Value="..\..\Asn1\X9\ClpDHValidationParams.pas"/>
+        <UnitName Value="ClpDHValidationParams"/>
       </Item356>
       <Item357>
-        <Filename Value="..\..\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas"/>
-        <UnitName Value="ClpDHBasicKeyPairGenerator"/>
+        <Filename Value="..\..\Utils\Randoms\ClpAESPRNGRandom.pas"/>
+        <UnitName Value="ClpAESPRNGRandom"/>
       </Item357>
       <Item358>
-        <Filename Value="..\..\Crypto\Generators\ClpDHKeyPairGenerator.pas"/>
-        <UnitName Value="ClpDHKeyPairGenerator"/>
+        <Filename Value="..\..\Asn1\CryptLib\ClpCryptLibObjectIdentifiers.pas"/>
+        <UnitName Value="ClpCryptLibObjectIdentifiers"/>
       </Item358>
       <Item359>
-        <Filename Value="..\..\Crypto\Generators\ClpDHParametersGenerator.pas"/>
-        <UnitName Value="ClpDHParametersGenerator"/>
+        <Filename Value="..\..\Interfaces\ClpIEndoPreCompInfo.pas"/>
+        <UnitName Value="ClpIEndoPreCompInfo"/>
       </Item359>
       <Item360>
-        <Filename Value="..\..\Crypto\Generators\ClpDHKeyGeneratorHelper.pas"/>
-        <UnitName Value="ClpDHKeyGeneratorHelper"/>
+        <Filename Value="..\..\Math\EC\Endo\ClpEndoPreCompInfo.pas"/>
+        <UnitName Value="ClpEndoPreCompInfo"/>
       </Item360>
       <Item361>
-        <Filename Value="..\..\Crypto\Generators\ClpDHParametersHelper.pas"/>
-        <UnitName Value="ClpDHParametersHelper"/>
+        <Filename Value="..\..\Math\EC\ClpScaleXNegateYPointMap.pas"/>
+        <UnitName Value="ClpScaleXNegateYPointMap"/>
       </Item361>
       <Item362>
-        <Filename Value="..\..\Crypto\Parameters\ClpDHPrivateKeyParameters.pas"/>
-        <UnitName Value="ClpDHPrivateKeyParameters"/>
+        <Filename Value="..\..\Math\EC\ClpScaleYNegateXPointMap.pas"/>
+        <UnitName Value="ClpScaleYNegateXPointMap"/>
       </Item362>
       <Item363>
-        <Filename Value="..\..\Crypto\Parameters\ClpDHPublicKeyParameters.pas"/>
-        <UnitName Value="ClpDHPublicKeyParameters"/>
+        <Filename Value="..\..\Math\EC\Endo\ClpGlvTypeAEndomorphism.pas"/>
+        <UnitName Value="ClpGlvTypeAEndomorphism"/>
       </Item363>
       <Item364>
-        <Filename Value="..\..\Crypto\Parameters\ClpDHKeyGenerationParameters.pas"/>
-        <UnitName Value="ClpDHKeyGenerationParameters"/>
+        <Filename Value="..\..\Math\EC\Endo\ClpGlvTypeAParameters.pas"/>
+        <UnitName Value="ClpGlvTypeAParameters"/>
       </Item364>
       <Item365>
-        <Filename Value="..\..\Crypto\Parameters\ClpDHKeyParameters.pas"/>
-        <UnitName Value="ClpDHKeyParameters"/>
+        <Filename Value="..\..\Math\EC\Endo\ClpScalarSplitParameters.pas"/>
+        <UnitName Value="ClpScalarSplitParameters"/>
       </Item365>
       <Item366>
-        <Filename Value="..\..\Crypto\Parameters\ClpDHValidationParameters.pas"/>
-        <UnitName Value="ClpDHValidationParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIGlvTypeAParameters.pas"/>
+        <UnitName Value="ClpIGlvTypeAParameters"/>
       </Item366>
       <Item367>
-        <Filename Value="..\..\Crypto\Parameters\ClpDHParameters.pas"/>
-        <UnitName Value="ClpDHParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIGlvTypeAEndomorphism.pas"/>
+        <UnitName Value="ClpIGlvTypeAEndomorphism"/>
       </Item367>
       <Item368>
-        <Filename Value="..\..\Asn1\X9\ClpDHDomainParameters.pas"/>
-        <UnitName Value="ClpDHDomainParameters"/>
+        <Filename Value="..\..\Interfaces\ClpIScaleXNegateYPointMap.pas"/>
+        <UnitName Value="ClpIScaleXNegateYPointMap"/>
       </Item368>
       <Item369>
-        <Filename Value="..\..\Asn1\X9\ClpDHValidationParams.pas"/>
-        <UnitName Value="ClpDHValidationParams"/>
+        <Filename Value="..\..\Interfaces\ClpIScaleYNegateXPointMap.pas"/>
+        <UnitName Value="ClpIScaleYNegateXPointMap"/>
       </Item369>
       <Item370>
-        <Filename Value="..\..\Utils\Randoms\ClpAESPRNGRandom.pas"/>
-        <UnitName Value="ClpAESPRNGRandom"/>
+        <Filename Value="..\..\Interfaces\ClpIScalarSplitParameters.pas"/>
+        <UnitName Value="ClpIScalarSplitParameters"/>
       </Item370>
+      <Item371>
+        <Filename Value="..\..\Math\EC\ClpECCompUtilities.pas"/>
+        <UnitName Value="ClpECCompUtilities"/>
+      </Item371>
+      <Item372>
+        <Filename Value="..\..\Math\EC\Multiplier\ClpValidityPreCompInfo.pas"/>
+        <UnitName Value="ClpValidityPreCompInfo"/>
+      </Item372>
+      <Item373>
+        <Filename Value="..\..\Interfaces\ClpIValidityPreCompInfo.pas"/>
+        <UnitName Value="ClpIValidityPreCompInfo"/>
+      </Item373>
     </Files>
     <RequiredPkgs Count="3">
       <Item1>

+ 41 - 40
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas

@@ -18,40 +18,35 @@ uses
   ClpECKeyParameters, ClpECPrivateKeyParameters, ClpECPublicKeyParameters, 
   ClpParametersWithRandom, ClpCryptoApiRandomGenerator, 
   ClpDigestRandomGenerator, ClpDsaDigestSigner, ClpECDsaSigner, 
-  ClpRandomDsaKCalculator, ClpIAbstractECMultiplier, 
-  ClpIAsymmetricCipherKeyPair, ClpIAsymmetricCipherKeyPairGenerator, 
-  ClpIAsymmetricKeyParameter, ClpICipherParameters, 
-  ClpICryptoApiRandomGenerator, ClpIDigestRandomGenerator, ClpIDsa, 
-  ClpIDsaDigestSigner, ClpIDsaKCalculator, ClpIECDomainParameters, 
-  ClpIECDsaSigner, ClpIECKeyGenerationParameters, ClpIECKeyPairGenerator, 
-  ClpIECKeyParameters, ClpIECPrivateKeyParameters, ClpIECPublicKeyParameters, 
-  ClpIExtensionField, ClpIFiniteField, ClpIFixedPointCombMultiplier, 
+  ClpRandomDsaKCalculator, ClpIAsymmetricCipherKeyPair, 
+  ClpIAsymmetricCipherKeyPairGenerator, ClpIAsymmetricKeyParameter, 
+  ClpICipherParameters, ClpICryptoApiRandomGenerator, 
+  ClpIDigestRandomGenerator, ClpIDsa, ClpIDsaDigestSigner, ClpIDsaKCalculator, 
+  ClpIECDomainParameters, ClpIECDsaSigner, ClpIECKeyGenerationParameters, 
+  ClpIECKeyPairGenerator, ClpIECKeyParameters, ClpIECPrivateKeyParameters, 
+  ClpIECPublicKeyParameters, ClpIExtensionField, ClpIFiniteField, 
   ClpIFixedPointPreCompInfo, ClpIGenericPolynomialExtensionField, 
-  ClpIGF2Polynomial, ClpIGlvEndomorphism, ClpIGlvMultiplier, 
-  ClpIGlvTypeBEndomorphism, ClpIGlvTypeBParameters, 
-  ClpIKeyGenerationParameters, ClpIOidTokenizer, ClpIParametersWithRandom, 
-  ClpIPolynomial, ClpIPolynomialExtensionField, ClpIPreCompInfo, 
-  ClpIPrimeField, ClpIRandom, ClpIRandomDsaKCalculator, ClpIRandomGenerator, 
-  ClpIRandomNumberGenerator, ClpIScaleXPointMap, ClpISecureRandom, ClpISigner, 
-  ClpIWNafL2RMultiplier, ClpIWNafPreCompInfo, ClpIWTauNafMultiplier, 
-  ClpIWTauNafPreCompInfo, ClpIX9ECParameters, ClpIX9ECParametersHolder, 
-  ClpIZTauElement, ClpBigInteger, ClpECAlgorithms, ClpLongArray, 
-  ClpScaleXPointMap, ClpSimpleBigDecimal, ClpTnaf, ClpZTauElement, 
-  ClpGlvTypeBEndomorphism, ClpGlvTypeBParameters, ClpAbstractECMultiplier, 
-  ClpFixedPointCombMultiplier, ClpFixedPointPreCompInfo, 
-  ClpFixedPointUtilities, ClpGlvMultiplier, ClpWNafL2RMultiplier, 
-  ClpWNafPreCompInfo, ClpWTauNafMultiplier, ClpWTauNafPreCompInfo, 
-  ClpFiniteFields, ClpGenericPolynomialExtensionField, ClpGF2Polynomial, 
-  ClpPrimeField, ClpMod, ClpNat, ClpDigestUtilities, ClpRandom, 
-  ClpSecureRandom, ClpSignerUtilities, ClpArrayUtils, ClpBigIntegers, 
-  ClpBitConverter, ClpBits, ClpConverters, ClpCryptoLibTypes, ClpTimes, 
-  ClpOSRandom, ClpRandomNumberGenerator, ClpSetWeakRef, ClpParameterUtilities, 
-  ClpGeneratorUtilities, ClpCipherUtilities, ClpIAesEngine, 
-  ClpIParametersWithIV, ClpIPaddedBufferedBlockCipher, ClpIKeyParameter, 
-  ClpIBufferedCipherBase, ClpIBufferedCipher, ClpIBufferedBlockCipher, 
-  ClpIBlockCipherPadding, ClpIBlockCipher, ClpPaddedBufferedBlockCipher, 
-  ClpParametersWithIV, ClpKeyParameter, ClpBufferedBlockCipher, 
-  ClpBufferedCipherBase, ClpCheck, ClpAesEngine, 
+  ClpIGF2Polynomial, ClpIGlvEndomorphism, ClpIGlvTypeBEndomorphism, 
+  ClpIGlvTypeBParameters, ClpIKeyGenerationParameters, ClpIOidTokenizer, 
+  ClpIParametersWithRandom, ClpIPolynomial, ClpIPolynomialExtensionField, 
+  ClpIPreCompInfo, ClpIPrimeField, ClpIRandom, ClpIRandomDsaKCalculator, 
+  ClpIRandomGenerator, ClpIRandomNumberGenerator, ClpIScaleXPointMap, 
+  ClpISecureRandom, ClpISigner, ClpIWNafPreCompInfo, ClpIWTauNafPreCompInfo, 
+  ClpIX9ECParameters, ClpIX9ECParametersHolder, ClpIZTauElement, 
+  ClpBigInteger, ClpECAlgorithms, ClpLongArray, ClpScaleXPointMap, 
+  ClpSimpleBigDecimal, ClpTnaf, ClpZTauElement, ClpGlvTypeBEndomorphism, 
+  ClpGlvTypeBParameters, ClpFixedPointPreCompInfo, ClpWNafPreCompInfo, 
+  ClpWTauNafPreCompInfo, ClpFiniteFields, ClpGenericPolynomialExtensionField, 
+  ClpGF2Polynomial, ClpPrimeField, ClpMod, ClpNat, ClpDigestUtilities, 
+  ClpRandom, ClpSecureRandom, ClpSignerUtilities, ClpArrayUtils, 
+  ClpBigIntegers, ClpBitConverter, ClpBits, ClpConverters, ClpCryptoLibTypes, 
+  ClpTimes, ClpOSRandom, ClpRandomNumberGenerator, ClpSetWeakRef, 
+  ClpParameterUtilities, ClpGeneratorUtilities, ClpCipherUtilities, 
+  ClpIAesEngine, ClpIParametersWithIV, ClpIPaddedBufferedBlockCipher, 
+  ClpIKeyParameter, ClpIBufferedCipherBase, ClpIBufferedCipher, 
+  ClpIBufferedBlockCipher, ClpIBlockCipherPadding, ClpIBlockCipher, 
+  ClpPaddedBufferedBlockCipher, ClpParametersWithIV, ClpKeyParameter, 
+  ClpBufferedBlockCipher, ClpBufferedCipherBase, ClpCheck, ClpAesEngine, 
   ClpPascalCoinECIESKdfBytesGenerator, ClpPascalCoinIESEngine, 
   ClpBaseKdfBytesGenerator, ClpIESEngine, ClpECIESPublicKeyParser, 
   ClpIESCipher, ClpECDHBasicAgreement, ClpEphemeralKeyPair, ClpKeyEncoder, 
@@ -79,12 +74,12 @@ uses
   ClpIECDHCBasicAgreement, ClpHMacDsaKCalculator, ClpIHMacDsaKCalculator, 
   ClpHkdfBytesGenerator, ClpIHkdfBytesGenerator, ClpHkdfParameters, 
   ClpIHkdfParameters, ClpDsaParameterGenerationParameters, 
-  ClpIDsaParameterGenerationParameters, ClpIValidityPrecompInfo, 
-  ClpDsaParametersGenerator, ClpDsaParameter, ClpIDsaParameter, 
-  ClpIKeyEncoder, ClpIDsaParametersGenerator, ClpIPreCompCallBack, 
-  ClpNistNamedCurves, ClpNat256, ClpNat320, ClpAesLightEngine, 
-  ClpIAesLightEngine, ClpCustomNamedCurves, ClpNat384, ClpNat192, ClpNat512, 
-  ClpInterleave, ClpBsiObjectIdentifiers, ClpEacObjectIdentifiers, ClpIDsaExt, 
+  ClpIDsaParameterGenerationParameters, ClpDsaParametersGenerator, 
+  ClpDsaParameter, ClpIDsaParameter, ClpIKeyEncoder, 
+  ClpIDsaParametersGenerator, ClpIPreCompCallBack, ClpNistNamedCurves, 
+  ClpNat256, ClpNat320, ClpAesLightEngine, ClpIAesLightEngine, 
+  ClpCustomNamedCurves, ClpNat384, ClpNat192, ClpNat512, ClpInterleave, 
+  ClpBsiObjectIdentifiers, ClpEacObjectIdentifiers, ClpIDsaExt, 
   ClpISchnorrDigestSigner, ClpIECSchnorrSipaSigner, ClpECSchnorrSipaSigner, 
   ClpSchnorrDigestSigner, ClpISchnorr, ClpISchnorrExt, ClpBlowfishEngine, 
   ClpIBlowfishEngine, ClpECC, ClpAsn1Objects, ClpSignersEncodings, 
@@ -133,7 +128,13 @@ uses
   ClpDHKeyGeneratorHelper, ClpDHParametersHelper, ClpDHPrivateKeyParameters, 
   ClpDHPublicKeyParameters, ClpDHKeyGenerationParameters, ClpDHKeyParameters, 
   ClpDHValidationParameters, ClpDHParameters, ClpDHDomainParameters, 
-  ClpDHValidationParams, ClpAESPRNGRandom;
+  ClpDHValidationParams, ClpAESPRNGRandom, ClpCryptLibObjectIdentifiers, 
+  ClpIEndoPreCompInfo, ClpEndoPreCompInfo, ClpScaleXNegateYPointMap, 
+  ClpScaleYNegateXPointMap, ClpGlvTypeAEndomorphism, ClpGlvTypeAParameters, 
+  ClpScalarSplitParameters, ClpIGlvTypeAParameters, ClpIGlvTypeAEndomorphism, 
+  ClpIScaleXNegateYPointMap, ClpIScaleYNegateXPointMap, 
+  ClpIScalarSplitParameters, ClpECCompUtilities, ClpValidityPreCompInfo, 
+  ClpIValidityPreCompInfo;
 
 implementation
 

+ 0 - 2
CryptoLib/src/Utils/Randoms/ClpAESPRNGRandom.pas

@@ -235,8 +235,6 @@ begin
       DoIncrementCounter;
       LResult := FCipher.DoFinal(FCounter);
       System.Move(LResult[0], data[LDatum], LDataLength * System.SizeOf(Byte));
-
-      // System.Inc(LDatum, LDataLength);
       System.Inc(FBytesSinceSeed, LDataLength);
     end;