Browse Source

Merge branch 'beta'

Ugochukwu Mmaduekwe 6 years ago
parent
commit
af58013e2f
71 changed files with 5612 additions and 3652 deletions
  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',
   ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
-  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -48,7 +47,6 @@ uses
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -69,10 +67,7 @@ uses
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.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',
   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',
   ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
@@ -107,14 +102,8 @@ uses
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
   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',
   ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.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',
   ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
@@ -221,8 +210,8 @@ uses
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.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',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
@@ -344,36 +333,52 @@ uses
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.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',
   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',
   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',
   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',
   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',
   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';
   UsageExamples in '..\src\UsageExamples.pas';
 
 
 begin
 begin

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

@@ -42,7 +42,6 @@ uses
   ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
-  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -58,7 +57,6 @@ uses
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -79,10 +77,7 @@ uses
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.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',
   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',
   ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
@@ -117,14 +112,8 @@ uses
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
   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',
   ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.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',
   ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
@@ -231,8 +220,8 @@ uses
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.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',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
@@ -384,6 +373,22 @@ uses
   ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
   ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
   ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpAESPRNGRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpAESPRNGRandom.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',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.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',
   ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
   ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
-  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
   ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -61,7 +60,6 @@ uses
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -82,10 +80,7 @@ uses
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.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',
   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',
   ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
   ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
@@ -120,14 +115,8 @@ uses
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
   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',
   ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.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',
   ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
   ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
@@ -234,8 +223,8 @@ uses
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.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',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
@@ -387,6 +376,22 @@ uses
   ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
   ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
   ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpAESPRNGRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpAESPRNGRandom.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',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',

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

@@ -43,15 +43,13 @@ type
   private
   private
 
 
   var
   var
-    Foid: string;
     Freq1, Freq2: TBytes;
     Freq1, Freq2: TBytes;
 
 
     procedure DoRecodeCheck(const oid: String; const enc: TBytes);
     procedure DoRecodeCheck(const oid: String; const enc: TBytes);
     procedure DoValidOidCheck(const oid: String);
     procedure DoValidOidCheck(const oid: String);
-    procedure DoInvalidOidCheck;
+    procedure DoInvalidOidCheck(const oid: String);
     procedure DoBranchCheck(const stem, branch: String);
     procedure DoBranchCheck(const stem, branch: String);
     procedure DoOnCheck(const stem, test: String; expected: Boolean);
     procedure DoOnCheck(const stem, test: String; expected: Boolean);
-    procedure DoConstructorMethod;
 
 
   protected
   protected
     procedure SetUp; override;
     procedure SetUp; override;
@@ -78,23 +76,18 @@ begin
     + branch);
     + branch);
 end;
 end;
 
 
-procedure TTestOID.DoConstructorMethod;
+procedure TTestOID.DoInvalidOidCheck(const oid: String);
 begin
 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;
 end;
 
 
 procedure TTestOID.DoOnCheck(const stem, test: String; expected: Boolean);
 procedure TTestOID.DoOnCheck(const stem, test: String; expected: Boolean);
@@ -145,40 +138,35 @@ begin
   DoRecodeCheck('1.2.54.34359733987.17', Freq2);
   DoRecodeCheck('1.2.54.34359733987.17', Freq2);
 
 
   DoValidOidCheck('0.1');
   DoValidOidCheck('0.1');
+  DoValidOidCheck('1.0');
+  DoValidOidCheck('1.0.2');
+  DoValidOidCheck('1.0.20');
+  DoValidOidCheck('1.0.200');
   DoValidOidCheck
   DoValidOidCheck
     ('1.1.127.32512.8323072.2130706432.545460846592.139637976727552.35747322042253312.9151314442816847872');
     ('1.1.127.32512.8323072.2130706432.545460846592.139637976727552.35747322042253312.9151314442816847872');
   DoValidOidCheck('1.2.123.12345678901.1.1.1');
   DoValidOidCheck('1.2.123.12345678901.1.1.1');
 
 
   DoValidOidCheck('2.25.196556539987194312349856245628873852187.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');
   DoBranchCheck('1.1', '2.2');
 
 

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

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

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

@@ -35,15 +35,23 @@ uses
   ClpIAsn1Objects,
   ClpIAsn1Objects,
   ClpIECC,
   ClpIECC,
   ClpECC,
   ClpECC,
+  ClpIDigest,
   ClpECNRSigner,
   ClpECNRSigner,
   ClpIECNRSigner,
   ClpIECNRSigner,
   ClpECDomainParameters,
   ClpECDomainParameters,
   ClpIECDomainParameters,
   ClpIECDomainParameters,
+  ClpIECKeyGenerationParameters,
+  ClpECKeyGenerationParameters,
   ClpECPrivateKeyParameters,
   ClpECPrivateKeyParameters,
   ClpIECPrivateKeyParameters,
   ClpIECPrivateKeyParameters,
   ClpECPublicKeyParameters,
   ClpECPublicKeyParameters,
   ClpIECPublicKeyParameters,
   ClpIECPublicKeyParameters,
+  ClpECKeyPairGenerator,
+  ClpIECKeyPairGenerator,
   ClpISigner,
   ClpISigner,
+  ClpIX9ECParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpECNamedCurveTable,
   ClpParametersWithRandom,
   ClpParametersWithRandom,
   ClpIParametersWithRandom,
   ClpIParametersWithRandom,
   ClpSecureRandom,
   ClpSecureRandom,
@@ -51,8 +59,10 @@ uses
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpSignerUtilities,
   ClpSignerUtilities,
   ClpBigInteger,
   ClpBigInteger,
+  ClpBigIntegers,
   ClpConverters,
   ClpConverters,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
+  ClpDigestUtilities,
   CryptoLibTestBase;
   CryptoLibTestBase;
 
 
 type
 type
@@ -121,6 +131,8 @@ type
     /// </summary>
     /// </summary>
     procedure TestECNR521bitPrimeSHA512; // SecP521r1
     procedure TestECNR521bitPrimeSHA512; // SecP521r1
 
 
+    procedure TestRange;
+
   end;
   end;
 
 
 implementation
 implementation
@@ -462,6 +474,79 @@ begin
   DoCheckSignature(521, priKey, pubKey, sgr, k, &message, r, s);
   DoCheckSignature(521, priKey, pubKey, sgr, k, &message, r, s);
 end;
 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
 initialization
 
 
 // Register any test cases with the test runner
 // Register any test cases with the test runner

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

@@ -26,6 +26,7 @@ interface
 uses
 uses
   Classes,
   Classes,
   SysUtils,
   SysUtils,
+  Math,
 {$IFDEF FPC}
 {$IFDEF FPC}
   fpcunit,
   fpcunit,
   testregistry,
   testregistry,
@@ -33,6 +34,7 @@ uses
   TestFramework,
   TestFramework,
 {$ENDIF FPC}
 {$ENDIF FPC}
   Generics.Collections,
   Generics.Collections,
+  ClpBits,
   ClpCustomNamedCurves,
   ClpCustomNamedCurves,
   ClpECNamedCurveTable,
   ClpECNamedCurveTable,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
@@ -41,10 +43,14 @@ uses
   ClpBigInteger,
   ClpBigInteger,
   ClpBigIntegers,
   ClpBigIntegers,
   ClpECAlgorithms,
   ClpECAlgorithms,
+  ClpECCompUtilities,
   ClpIFiniteField,
   ClpIFiniteField,
   ClpIX9ECParameters,
   ClpIX9ECParameters,
+  ClpIX9ECC,
+  ClpX9ECC,
   ClpECC,
   ClpECC,
   ClpIECC,
   ClpIECC,
+  ClpX9ECParameters,
   CryptoLibTestBase;
   CryptoLibTestBase;
 
 
 type
 type
@@ -73,7 +79,9 @@ type
   // */
   // */
   TF2m = class
   TF2m = class
 
 
-  public const
+  public
+
+    const
     // Irreducible polynomial for TPB z^4 + z + 1
     // Irreducible polynomial for TPB z^4 + z + 1
     m = Int32(4);
     m = Int32(4);
 
 
@@ -200,6 +208,16 @@ type
     procedure ImplAddSubtractMultiplyTwiceEncodingTestAllCoords
     procedure ImplAddSubtractMultiplyTwiceEncodingTestAllCoords
       (const x9ECParameters: IX9ECParameters);
       (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
   protected
     procedure SetUp; override;
     procedure SetUp; override;
     procedure TearDown; override;
     procedure TearDown; override;
@@ -245,6 +263,8 @@ type
     // */
     // */
     procedure TestAddSubtractMultiplyTwiceEncoding();
     procedure TestAddSubtractMultiplyTwiceEncoding();
 
 
+    procedure TestExampleFpB0();
+
   end;
   end;
 
 
 implementation
 implementation
@@ -289,11 +309,28 @@ begin
   CheckEquals(True, b.Equals(a), msg);
   CheckEquals(True, b.Equals(a), msg);
 end;
 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
 procedure TTestECPoint.ImplAddSubtractMultiplyTwiceEncodingTest
   (const curve: IECCurve; const q: IECPoint; const n: TBigInteger);
   (const curve: IECCurve; const q: IECPoint; const n: TBigInteger);
 var
 var
   infinity, p: IECPoint;
   infinity, p: IECPoint;
-  i: Int32;
+  i, logSize, rounds: Int32;
 begin
 begin
   // Get point at infinity on the curve
   // Get point at infinity on the curve
   infinity := curve.infinity;
   infinity := curve.infinity;
@@ -301,10 +338,13 @@ begin
   ImplTestAddSubtract(q, infinity);
   ImplTestAddSubtract(q, infinity);
   ImplTestMultiply(q, n.BitLength);
   ImplTestMultiply(q, n.BitLength);
   ImplTestMultiply(infinity, n.BitLength);
   ImplTestMultiply(infinity, n.BitLength);
-  //
+
+  logSize := 32 - TBits.NumberOfLeadingZeros(curve.FieldSize - 1);
+  rounds := Max(2, Min(10, 32 - 3 * logSize));
+
   p := q;
   p := q;
   i := 0;
   i := 0;
-  while i < 10 do
+  while i < rounds do
   begin
   begin
     ImplTestEncoding(p);
     ImplTestEncoding(p);
     p := p.Twice();
     p := p.Twice();
@@ -509,18 +549,47 @@ end;
 procedure TTestECPoint.ImplValidityTest(const c: IECCurve; const g: IECPoint);
 procedure TTestECPoint.ImplValidityTest(const c: IECCurve; const g: IECPoint);
 var
 var
   h: TBigInteger;
   h: TBigInteger;
-  order2, bad: IECPoint;
+  sqrtB, L, T, x, y: IECFieldElement;
+  order2, bad2, good2, order4, bad4_1, bad4_2, bad4_3, good4: IECPoint;
 begin
 begin
   CheckTrue(g.IsValid());
   CheckTrue(g.IsValid());
 
 
-  h := c.getCofactor();
-  if ((h.IsInitialized) and (h.CompareTo(TBigInteger.One) > 0)) then
+  if (TECAlgorithms.IsF2mCurve(c)) then
   begin
   begin
-    if (TECAlgorithms.IsF2mCurve(c)) then
+    h := c.Cofactor;
+    if (h.IsInitialized) then
     begin
     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;
   end;
 end;
 end;
@@ -535,6 +604,51 @@ begin
   F2mInstance.CreatePoints;
   F2mInstance.CreatePoints;
 end;
 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;
 procedure TTestECPoint.TearDown;
 begin
 begin
   inherited;
   inherited;
@@ -722,6 +836,48 @@ begin
   ImplTestTwice(F2mInstance.Fp);
   ImplTestTwice(F2mInstance.Fp);
 end;
 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 }
 { TFp }
 
 
 constructor TFp.Create;
 constructor TFp.Create;

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

@@ -4838,51 +4838,48 @@ end;
 class function TDerObjectIdentifier.IsValidBranchID(const branchID: String;
 class function TDerObjectIdentifier.IsValidBranchID(const branchID: String;
   start: Int32): Boolean;
   start: Int32): Boolean;
 var
 var
-  periodAllowed: Boolean;
-  Pos: Int32;
+  digitCount, Pos: Int32;
   ch: Char;
   ch: Char;
 begin
 begin
-  periodAllowed := False;
+  digitCount := 0;
 
 
   Pos := System.length(branchID) + 1;
   Pos := System.length(branchID) + 1;
   System.Dec(Pos);
   System.Dec(Pos);
+
   while (Pos >= start) do
   while (Pos >= start) do
   begin
   begin
     ch := branchID[Pos];
     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
     if (ch = '.') then
     begin
     begin
-      if (not(periodAllowed)) then
+      if ((digitCount = 0) or ((digitCount > 1) and (branchID[Pos + 1] = '0')))
+      then
       begin
       begin
         result := False;
         result := False;
         Exit;
         Exit;
       end;
       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;
     end;
+    System.Dec(Pos);
+  end;
 
 
+  if ((digitCount = 0) or ((digitCount > 1) and (branchID[Pos + 1] = '0'))) then
+  begin
     result := False;
     result := False;
     Exit;
     Exit;
   end;
   end;
 
 
-  result := periodAllowed;
+  result := True;
 end;
 end;
 
 
 class function TDerObjectIdentifier.IsValidIdentifier(const identifier
 class function TDerObjectIdentifier.IsValidIdentifier(const identifier
@@ -4897,11 +4894,7 @@ begin
   end;
   end;
 
 
   first := identifier[1];
   first := identifier[1];
-  // if ((first < '0') or (first > '2')) then
-  // begin
-  // result := false;
-  // Exit;
-  // end;
+
   if (not CharInSet(first, ['0' .. '2'])) then
   if (not CharInSet(first, ['0' .. '2'])) then
   begin
   begin
     result := False;
     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,
   ClpIGlvTypeBEndomorphism,
   ClpSecObjectIdentifiers,
   ClpSecObjectIdentifiers,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
+  ClpECCompUtilities,
   ClpBigInteger,
   ClpBigInteger,
   ClpECC,
   ClpECC,
   ClpIECC,
   ClpIECC,
@@ -36,6 +37,8 @@ uses
   ClpIX9ECC,
   ClpIX9ECC,
   ClpIAsn1Objects,
   ClpIAsn1Objects,
   ClpGlvTypeBEndomorphism,
   ClpGlvTypeBEndomorphism,
+  ClpIScalarSplitParameters,
+  ClpScalarSplitParameters,
   ClpX9ECParameters,
   ClpX9ECParameters,
   ClpIX9ECParameters,
   ClpIX9ECParameters,
   ClpX9ECParametersHolder,
   ClpX9ECParametersHolder,
@@ -63,6 +66,9 @@ type
       const p: IGlvTypeBParameters): IECCurve; static; inline;
       const p: IGlvTypeBParameters): IECCurve; static; inline;
     class function FromHex(const Hex: String): TBigInteger; 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 procedure Boot(); static;
     class constructor CreateSecNamedCurves();
     class constructor CreateSecNamedCurves();
     class destructor DestroySecNamedCurves();
     class destructor DestroySecNamedCurves();
@@ -347,7 +353,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(113);
+      M = Int32(113);
       Fk = Int32(9);
       Fk = Int32(9);
 
 
     strict protected
     strict protected
@@ -368,7 +374,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(113);
+      M = Int32(113);
       Fk = Int32(9);
       Fk = Int32(9);
 
 
     strict protected
     strict protected
@@ -389,10 +395,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -412,10 +418,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -435,10 +441,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -458,10 +464,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -481,10 +487,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -504,7 +510,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(193);
+      M = Int32(193);
       Fk = Int32(15);
       Fk = Int32(15);
 
 
     strict protected
     strict protected
@@ -525,7 +531,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(193);
+      M = Int32(193);
       Fk = Int32(15);
       Fk = Int32(15);
 
 
     strict protected
     strict protected
@@ -546,7 +552,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(233);
+      M = Int32(233);
       Fk = Int32(74);
       Fk = Int32(74);
 
 
     strict protected
     strict protected
@@ -567,7 +573,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(233);
+      M = Int32(233);
       Fk = Int32(74);
       Fk = Int32(74);
 
 
     strict protected
     strict protected
@@ -588,7 +594,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(239);
+      M = Int32(239);
       Fk = Int32(158);
       Fk = Int32(158);
 
 
     strict protected
     strict protected
@@ -609,10 +615,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -632,10 +638,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -655,7 +661,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(409);
+      M = Int32(409);
       Fk = Int32(87);
       Fk = Int32(87);
 
 
     strict protected
     strict protected
@@ -676,7 +682,7 @@ type
 
 
     strict private
     strict private
     const
     const
-      Fm = Int32(409);
+      M = Int32(409);
       Fk = Int32(87);
       Fk = Int32(87);
 
 
     strict protected
     strict protected
@@ -697,10 +703,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -720,10 +726,10 @@ type
 
 
     strict private
     strict private
     const
     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
     strict protected
       function CreateParameters(): IX9ECParameters; override;
       function CreateParameters(): IX9ECParameters; override;
@@ -739,6 +745,13 @@ implementation
 
 
 { TSecNamedCurves }
 { 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;
 class procedure TSecNamedCurves.DefineCurve(const name: String;
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
 begin
 begin
@@ -922,9 +935,8 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -952,9 +964,8 @@ begin
   h := TBigInteger.ValueOf(4);
   h := TBigInteger.ValueOf(4);
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -982,9 +993,8 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1012,9 +1022,8 @@ begin
   h := TBigInteger.ValueOf(4);
   h := TBigInteger.ValueOf(4);
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1045,19 +1054,20 @@ begin
   glv := TGlvTypeBParameters.Create
   glv := TGlvTypeBParameters.Create
     (TBigInteger.Create('9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a', 16),
     (TBigInteger.Create('9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a', 16),
     TBigInteger.Create('c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4', 16),
     TBigInteger.Create('c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('9162fbe73984472a0a9e', 16),
     (TBigInteger.Create('9162fbe73984472a0a9e', 16),
     TBigInteger.Create('-96341f1138933bc2f505', 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);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1085,9 +1095,8 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1115,9 +1124,8 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1148,19 +1156,20 @@ begin
   glv := TGlvTypeBParameters.Create
   glv := TGlvTypeBParameters.Create
     (TBigInteger.Create('bb85691939b869c1d087f601554b96b80cb4f55b35f433c2', 16),
     (TBigInteger.Create('bb85691939b869c1d087f601554b96b80cb4f55b35f433c2', 16),
     TBigInteger.Create('3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1', 16),
     TBigInteger.Create('3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('71169be7330b3038edb025f1', 16),
     (TBigInteger.Create('71169be7330b3038edb025f1', 16),
     TBigInteger.Create('-b3fb3400dec5c4adceb8655c', 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('71169be7330b3038edb025f1', 16)),
     TBigInteger.Create('71169be7330b3038edb025f1d0f9', 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);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1188,9 +1197,8 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1223,20 +1231,19 @@ begin
     ('fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768', 16),
     ('fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768', 16),
     TBigInteger.Create
     TBigInteger.Create
     ('60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788', 16),
     ('60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('6b8cf07d4ca75c88957d9d670591', 16),
     (TBigInteger.Create('6b8cf07d4ca75c88957d9d670591', 16),
     TBigInteger.Create('-b8adf1378a6eb73409fa6c9c637d', 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('6b8cf07d4ca75c88957d9d670591', 16)),
     TBigInteger.Create('6b8cf07d4ca75c88957d9d67059037a4', 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);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1264,10 +1271,8 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1302,20 +1307,20 @@ begin
     ('7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', 16),
     ('7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', 16),
     TBigInteger.Create
     TBigInteger.Create
     ('5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', 16),
     ('5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16),
     (TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16),
     TBigInteger.Create('-e4437ed6010e88286f547fa90abfe4c3', 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('3086d221a7d46bcde86c90e49284eb15', 16)),
     TBigInteger.Create('3086d221a7d46bcde86c90e49284eb153dab', 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);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1347,10 +1352,8 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1382,11 +1385,9 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1418,11 +1419,9 @@ begin
   h := TBigInteger.One;
   h := TBigInteger.One;
 
 
   curve := ConfigureCurve(TFpCurve.Create(p, a, b, n, h) as IFpCurve);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1447,10 +1446,9 @@ begin
   n := FromHex('0100000000000000D9CCEC8A39E56F');
   n := FromHex('0100000000000000D9CCEC8A39E56F');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1475,10 +1473,9 @@ begin
   n := FromHex('010000000000000108789B2496AF93');
   n := FromHex('010000000000000108789B2496AF93');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1503,10 +1500,10 @@ begin
   n := FromHex('0400000000000000023123953A9464B54D');
   n := FromHex('0400000000000000023123953A9464B54D');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1531,10 +1528,10 @@ begin
   n := FromHex('0400000000000000016954A233049BA98F');
   n := FromHex('0400000000000000016954A233049BA98F');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1559,10 +1556,10 @@ begin
   n := FromHex('04000000000000000000020108A2E0CC0D99F8A5EF');
   n := FromHex('04000000000000000000020108A2E0CC0D99F8A5EF');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1587,10 +1584,10 @@ begin
   n := FromHex('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B');
   n := FromHex('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1615,10 +1612,10 @@ begin
   n := FromHex('040000000000000000000292FE77E70C12A4234C33');
   n := FromHex('040000000000000000000292FE77E70C12A4234C33');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1643,10 +1640,9 @@ begin
   n := FromHex('01000000000000000000000000C7F34A778F443ACC920EBA49');
   n := FromHex('01000000000000000000000000C7F34A778F443ACC920EBA49');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1671,10 +1667,9 @@ begin
   n := FromHex('010000000000000000000000015AAB561B005413CCD4EE99D5');
   n := FromHex('010000000000000000000000015AAB561B005413CCD4EE99D5');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1699,11 +1694,9 @@ begin
   n := FromHex('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF');
   n := FromHex('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF');
   h := TBigInteger.ValueOf(4);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1728,11 +1721,9 @@ begin
   n := FromHex('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7');
   n := FromHex('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1757,11 +1748,9 @@ begin
   n := FromHex('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5');
   n := FromHex('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5');
   h := TBigInteger.ValueOf(4);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1787,12 +1776,11 @@ begin
     ('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61');
     ('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61');
   h := TBigInteger.ValueOf(4);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1819,12 +1807,11 @@ begin
     ('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307');
     ('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1850,12 +1837,10 @@ begin
     ('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF');
     ('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF');
   h := TBigInteger.ValueOf(4);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1882,12 +1867,10 @@ begin
     ('010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173');
     ('010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1913,12 +1896,11 @@ begin
     ('020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001');
     ('020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001');
   h := TBigInteger.ValueOf(4);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;
@@ -1945,12 +1927,11 @@ begin
     ('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47');
     ('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47');
   h := TBigInteger.ValueOf(2);
   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);
   result := TX9ECParameters.Create(curve, G, n, h, S);
 end;
 end;

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

@@ -28,6 +28,7 @@ uses
   ClpTeleTrusTObjectIdentifiers,
   ClpTeleTrusTObjectIdentifiers,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpBigInteger,
   ClpBigInteger,
+  ClpECCompUtilities,
   ClpECC,
   ClpECC,
   ClpIECC,
   ClpIECC,
   ClpX9ECC,
   ClpX9ECC,
@@ -61,6 +62,9 @@ type
     class function ConfigureCurve(const curve: IECCurve): IECCurve;
     class function ConfigureCurve(const curve: IECCurve): IECCurve;
       static; inline;
       static; inline;
 
 
+    class function ConfigureBasepoint(const curve: IECCurve;
+      const encoding: String): IX9ECPoint; static;
+
     class procedure Boot(); static;
     class procedure Boot(); static;
     class constructor CreateTeleTrusTNamedCurves();
     class constructor CreateTeleTrusTNamedCurves();
     class destructor DestroyTeleTrusTNamedCurves();
     class destructor DestroyTeleTrusTNamedCurves();
@@ -325,6 +329,13 @@ implementation
 
 
 { TeleTrusTNamedCurves }
 { 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)
 class function TTeleTrusTNamedCurves.ConfigureCurve(const curve: IECCurve)
   : IECCurve;
   : IECCurve;
 begin
 begin
@@ -448,6 +459,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP160r1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create('E95E4A5F737059DC60DF5991D45029409E60FC09', 16);
   n := TBigInteger.Create('E95E4A5F737059DC60DF5991D45029409E60FC09', 16);
   h := TBigInteger.Create('01', 16);
   h := TBigInteger.Create('01', 16);
@@ -459,11 +471,10 @@ begin
     TBigInteger.Create('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16), // b
     TBigInteger.Create('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16), // b
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP160r1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP160r1Holder.Instance
@@ -479,6 +490,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP160t1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create('E95E4A5F737059DC60DF5991D45029409E60FC09', 16);
   n := TBigInteger.Create('E95E4A5F737059DC60DF5991D45029409E60FC09', 16);
   h := TBigInteger.Create('01', 16);
   h := TBigInteger.Create('01', 16);
@@ -490,11 +502,10 @@ begin
     TBigInteger.Create('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16), // b'
     TBigInteger.Create('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16), // b'
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP160t1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP160t1Holder.Instance
@@ -510,6 +521,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP192r1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16);
     ('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16);
@@ -524,11 +536,10 @@ begin
     // b
     // b
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP192r1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP192r1Holder.Instance
@@ -544,6 +555,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP192t1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16);
     ('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16);
@@ -558,11 +570,10 @@ begin
     // b'
     // b'
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP192t1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP192t1Holder.Instance
@@ -578,6 +589,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP224r1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16);
     ('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16);
@@ -594,11 +606,10 @@ begin
     // b
     // b
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP224r1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP224r1Holder.Instance
@@ -614,6 +625,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP224t1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16);
     ('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16);
@@ -630,11 +642,10 @@ begin
     // b'
     // b'
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP224t1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP224t1Holder.Instance
@@ -650,6 +661,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP256r1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16);
     ('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16);
@@ -667,11 +679,10 @@ begin
     // b
     // b
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP256r1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP256r1Holder.Instance
@@ -687,6 +698,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP256t1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16);
     ('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16);
@@ -704,11 +716,10 @@ begin
     // b'
     // b'
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP256t1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP256t1Holder.Instance
@@ -765,6 +776,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP320t1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311',
     ('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311',
@@ -786,11 +798,10 @@ begin
     // b'
     // b'
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP320t1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP320t1Holder.Instance
@@ -806,6 +817,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP384r1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
     ('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
@@ -827,11 +839,10 @@ begin
     // b
     // b
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP384r1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP384r1Holder.Instance
@@ -847,6 +858,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP384t1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
     ('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
@@ -868,11 +880,10 @@ begin
     // b'
     // b'
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP384t1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP384t1Holder.Instance
@@ -888,6 +899,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP512r1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
     ('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
@@ -909,12 +921,11 @@ begin
     // b
     // b
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP512r1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP512r1Holder.Instance
@@ -930,6 +941,7 @@ function TTeleTrusTNamedCurves.TBrainpoolP512t1Holder.CreateParameters
 var
 var
   n, h: TBigInteger;
   n, h: TBigInteger;
   curve: IECCurve;
   curve: IECCurve;
+  G: IX9ECPoint;
 begin
 begin
   n := TBigInteger.Create
   n := TBigInteger.Create
     ('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
     ('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
@@ -951,12 +963,11 @@ begin
     // b'
     // b'
     n, h) as IFpCurve);
     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;
 end;
 
 
 class function TTeleTrusTNamedCurves.TBrainpoolP512t1Holder.Instance
 class function TTeleTrusTNamedCurves.TBrainpoolP512t1Holder.Instance

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

@@ -28,9 +28,11 @@ uses
   ClpGlvTypeBParameters,
   ClpGlvTypeBParameters,
   ClpIGlvTypeBEndomorphism,
   ClpIGlvTypeBEndomorphism,
   ClpSecObjectIdentifiers,
   ClpSecObjectIdentifiers,
+  ClpCryptLibObjectIdentifiers,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpBigInteger,
   ClpBigInteger,
   ClpECC,
   ClpECC,
+  ClpECCompUtilities,
   ClpSecP256K1Custom,
   ClpSecP256K1Custom,
   ClpISecP256K1Custom,
   ClpISecP256K1Custom,
   ClpSecP256R1Custom,
   ClpSecP256R1Custom,
@@ -47,6 +49,8 @@ uses
   ClpX9ECC,
   ClpX9ECC,
   ClpIX9ECC,
   ClpIX9ECC,
   ClpIAsn1Objects,
   ClpIAsn1Objects,
+  ClpScalarSplitParameters,
+  ClpIScalarSplitParameters,
   ClpGlvTypeBEndomorphism,
   ClpGlvTypeBEndomorphism,
   ClpX9ECParameters,
   ClpX9ECParameters,
   ClpIX9ECParameters,
   ClpIX9ECParameters,
@@ -69,8 +73,8 @@ type
 
 
     class function GetNames: TCryptoLibStringArray; static; inline;
     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;
     class procedure DefineCurveWithOid(const name: String;
       const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
       const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
@@ -84,6 +88,9 @@ type
     class function ConfigureCurveGlv(const c: IECCurve;
     class function ConfigureCurveGlv(const c: IECCurve;
       const p: IGlvTypeBParameters): IECCurve; static; inline;
       const p: IGlvTypeBParameters): IECCurve; static; inline;
 
 
+    class function ConfigureBasepoint(const curve: IECCurve;
+      const encoding: String): IX9ECPoint; static;
+
     class procedure Boot(); static;
     class procedure Boot(); static;
     class constructor CreateCustomNamedCurves();
     class constructor CreateCustomNamedCurves();
     class destructor DestroyCustomNamedCurves();
     class destructor DestroyCustomNamedCurves();
@@ -220,17 +227,24 @@ implementation
 
 
 { TCustomNamedCurves }
 { 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
 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;
 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;
 class procedure TCustomNamedCurves.DefineCurveWithOid(const name: String;
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
 var
 var
@@ -353,7 +367,8 @@ begin
 
 
   Fnames := TList<String>.Create();
   Fnames := TList<String>.Create();
 
 
-  DefineCurve('curve25519', TCurve25519Holder.Instance);
+  DefineCurveWithOid('curve25519', TCryptlibObjectIdentifiers.Curvey25519,
+    TCurve25519Holder.Instance);
 
 
   DefineCurveWithOid('secp256k1', TSecObjectIdentifiers.SecP256k1,
   DefineCurveWithOid('secp256k1', TSecObjectIdentifiers.SecP256k1,
     TSecP256K1Holder.Instance);
     TSecP256K1Holder.Instance);
@@ -397,10 +412,8 @@ begin
     *
     *
     * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
     * (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);
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 end;
@@ -426,19 +439,19 @@ begin
     ('7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', 16),
     ('7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', 16),
     TBigInteger.Create
     TBigInteger.Create
     ('5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', 16),
     ('5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', 16),
-    TCryptoLibGenericArray<TBigInteger>.Create
+
+    TScalarSplitParameters.Create(TCryptoLibGenericArray<TBigInteger>.Create
     (TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16),
     (TBigInteger.Create('3086d221a7d46bcde86c90e49284eb15', 16),
     TBigInteger.Create('-e4437ed6010e88286f547fa90abfe4c3', 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('3086d221a7d46bcde86c90e49284eb15', 16)),
     TBigInteger.Create('3086d221a7d46bcde86c90e49284eb153dab', 16),
     TBigInteger.Create('3086d221a7d46bcde86c90e49284eb153dab', 16),
-    TBigInteger.Create('e4437ed6010e88286f547fa90abfe4c42212', 16), 272);
+    TBigInteger.Create('e4437ed6010e88286f547fa90abfe4c42212', 16), 272)
+    as IScalarSplitParameters);
   curve := ConfigureCurveGlv(TSecP256K1Curve.Create() as ISecP256K1Curve, glv);
   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);
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 end;
 
 
@@ -458,11 +471,9 @@ var
 begin
 begin
   S := THex.Decode('A335926AA319A27A1D00896A6773A4827ACDAC73');
   S := THex.Decode('A335926AA319A27A1D00896A6773A4827ACDAC73');
   curve := ConfigureCurve(TSecP384R1Curve.Create() as ISecP384R1Curve);
   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);
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 end;
 
 
@@ -482,11 +493,9 @@ var
 begin
 begin
   S := THex.Decode('D09E8800291CB85396CC6717393284AAA0DA64BA');
   S := THex.Decode('D09E8800291CB85396CC6717393284AAA0DA64BA');
   curve := ConfigureCurve(TSecP521R1Curve.Create() as ISecP521R1Curve);
   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);
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 end;
 
 
@@ -506,11 +515,9 @@ var
 begin
 begin
   S := Nil;
   S := Nil;
   curve := ConfigureCurve(TSecT283K1Curve.Create() as ISecT283K1Curve);
   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);
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 end;
 
 
@@ -530,10 +537,9 @@ var
 begin
 begin
   S := THex.Decode('C49D360886E704936A6678E1139D26B7819F7E90');
   S := THex.Decode('C49D360886E704936A6678E1139D26B7819F7E90');
   curve := ConfigureCurve(TSecP256R1Curve.Create() as ISecP256R1Curve);
   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);
   result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
 end;
 end;
 
 

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

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

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

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

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

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

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

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

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

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

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

@@ -27,6 +27,7 @@ uses
   ClpIECC,
   ClpIECC,
   ClpIECNRSigner,
   ClpIECNRSigner,
   ClpBigInteger,
   ClpBigInteger,
+  ClpBigIntegers,
   ClpISecureRandom,
   ClpISecureRandom,
   ClpIECKeyParameters,
   ClpIECKeyParameters,
   ClpIParametersWithRandom,
   ClpIParametersWithRandom,
@@ -47,29 +48,45 @@ resourcestring
   SECPrivateKeyNotFound = 'EC Private Key Required for Signing';
   SECPrivateKeyNotFound = 'EC Private Key Required for Signing';
   SNotInitializedForSigning = 'Not Initialised For Signing';
   SNotInitializedForSigning = 'Not Initialised For Signing';
   SNotInitializedForVerifying = 'Not Initialised For Verifying';
   SNotInitializedForVerifying = 'Not Initialised For Verifying';
+  SNotInitializedForVerifyingRecovery =
+    'Not Initialised For Verifying/Recovery';
   SInputTooLargeForECNRKey = 'Input Too Large For ECNR Key.';
   SInputTooLargeForECNRKey = 'Input Too Large For ECNR Key.';
 
 
 type
 type
 
 
   /// <summary>
   /// <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>
   /// </summary>
   TECNRSigner = class sealed(TInterfacedObject, IDsaExt, IECNRSigner)
   TECNRSigner = class sealed(TInterfacedObject, IDsaExt, IECNRSigner)
 
 
   strict private
   strict private
   var
   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
   public
 
 
     property Order: TBigInteger read GetOrder;
     property Order: TBigInteger read GetOrder;
     property AlgorithmName: String read GetAlgorithmName;
     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;
     procedure Init(forSigning: Boolean;
       const parameters: ICipherParameters); virtual;
       const parameters: ICipherParameters); virtual;
 
 
@@ -121,23 +138,72 @@ type
     function VerifySignature(const &message: TCryptoLibByteArray;
     function VerifySignature(const &message: TCryptoLibByteArray;
       const r, s: TBigInteger): Boolean;
       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;
   end;
 
 
 implementation
 implementation
 
 
 { TECNRSigner }
 { 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)
 function TECNRSigner.GenerateSignature(const &message: TCryptoLibByteArray)
   : TCryptoLibGenericArray<TBigInteger>;
   : TCryptoLibGenericArray<TBigInteger>;
 var
 var
   n, e, r, s, Vx, x, u: TBigInteger;
   n, e, r, s, Vx, x, u: TBigInteger;
-  nBitLength, eBitLength: Int32;
   privKey: IECPrivateKeyParameters;
   privKey: IECPrivateKeyParameters;
   tempPair: IAsymmetricCipherKeyPair;
   tempPair: IAsymmetricCipherKeyPair;
   keyGen: IECKeyPairGenerator;
   keyGen: IECKeyPairGenerator;
   V: IECPublicKeyParameters;
   V: IECPublicKeyParameters;
 begin
 begin
-  if (not FforSigning) then
+  if (not FForSigning) then
   begin
   begin
     // not properly initialized... deal with it
     // not properly initialized... deal with it
     raise EInvalidOperationCryptoLibException.CreateRes
     raise EInvalidOperationCryptoLibException.CreateRes
@@ -145,14 +211,12 @@ begin
   end;
   end;
 
 
   n := Order;
   n := Order;
-  nBitLength := n.BitLength;
 
 
   e := TBigInteger.Create(1, &message);
   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
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputTooLargeForECNRKey);
     raise EDataLengthCryptoLibException.CreateRes(@SInputTooLargeForECNRKey);
   end;
   end;
@@ -162,7 +226,7 @@ begin
     // the same EC parameters
     // the same EC parameters
     keyGen := TECKeyPairGenerator.Create();
     keyGen := TECKeyPairGenerator.Create();
 
 
-    keyGen.Init(TECKeyGenerationParameters.Create(privKey.parameters, Frandom)
+    keyGen.Init(TECKeyGenerationParameters.Create(privKey.parameters, FRandom)
       as IECKeyGenerationParameters);
       as IECKeyGenerationParameters);
 
 
     tempPair := keyGen.GenerateKeyPair();
     tempPair := keyGen.GenerateKeyPair();
@@ -189,7 +253,7 @@ end;
 
 
 function TECNRSigner.GetOrder: TBigInteger;
 function TECNRSigner.GetOrder: TBigInteger;
 begin
 begin
-  result := Fkey.parameters.n;
+  result := FKey.parameters.n;
 end;
 end;
 
 
 procedure TECNRSigner.Init(forSigning: Boolean;
 procedure TECNRSigner.Init(forSigning: Boolean;
@@ -198,19 +262,19 @@ var
   rParam: IParametersWithRandom;
   rParam: IParametersWithRandom;
   Lparameters: ICipherParameters;
   Lparameters: ICipherParameters;
 begin
 begin
-  FforSigning := forSigning;
+  FForSigning := forSigning;
   Lparameters := parameters;
   Lparameters := parameters;
   if (forSigning) then
   if (forSigning) then
   begin
   begin
 
 
     if (Supports(Lparameters, IParametersWithRandom, rParam)) then
     if (Supports(Lparameters, IParametersWithRandom, rParam)) then
     begin
     begin
-      Frandom := rParam.random;
+      FRandom := rParam.random;
       Lparameters := rParam.parameters;
       Lparameters := rParam.parameters;
     end
     end
     else
     else
     begin
     begin
-      Frandom := TSecureRandom.Create();
+      FRandom := TSecureRandom.Create();
     end;
     end;
 
 
     if (not(Supports(Lparameters, IECPrivateKeyParameters))) then
     if (not(Supports(Lparameters, IECPrivateKeyParameters))) then
@@ -218,7 +282,7 @@ begin
       raise EInvalidKeyCryptoLibException.CreateRes(@SECPrivateKeyNotFound);
       raise EInvalidKeyCryptoLibException.CreateRes(@SECPrivateKeyNotFound);
     end;
     end;
 
 
-    Fkey := Lparameters as IECPrivateKeyParameters;
+    FKey := Lparameters as IECPrivateKeyParameters;
   end
   end
   else
   else
   begin
   begin
@@ -227,7 +291,7 @@ begin
       raise EInvalidKeyCryptoLibException.CreateRes(@SECPublicKeyNotFound);
       raise EInvalidKeyCryptoLibException.CreateRes(@SECPublicKeyNotFound);
     end;
     end;
 
 
-    Fkey := Lparameters as IECPublicKeyParameters;
+    FKey := Lparameters as IECPublicKeyParameters;
   end;
   end;
 end;
 end;
 
 
@@ -235,18 +299,17 @@ function TECNRSigner.VerifySignature(const &message: TCryptoLibByteArray;
   const r, s: TBigInteger): Boolean;
   const r, s: TBigInteger): Boolean;
 var
 var
   pubKey: IECPublicKeyParameters;
   pubKey: IECPublicKeyParameters;
-  n, e, x, t: TBigInteger;
+  n, e, t: TBigInteger;
   nBitLength, eBitLength: Int32;
   nBitLength, eBitLength: Int32;
-  G, W, P: IECPoint;
 begin
 begin
-  if (FforSigning) then
+  if (FForSigning) then
   begin
   begin
     // not properly initialized... deal with it
     // not properly initialized... deal with it
     raise EInvalidOperationCryptoLibException.CreateRes
     raise EInvalidOperationCryptoLibException.CreateRes
       (@SNotInitializedForVerifying);
       (@SNotInitializedForVerifying);
   end;
   end;
 
 
-  pubKey := Fkey as IECPublicKeyParameters;
+  pubKey := FKey as IECPublicKeyParameters;
   n := pubKey.parameters.n;
   n := pubKey.parameters.n;
   nBitLength := n.BitLength;
   nBitLength := n.BitLength;
 
 
@@ -258,37 +321,31 @@ begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputTooLargeForECNRKey);
     raise EDataLengthCryptoLibException.CreateRes(@SInputTooLargeForECNRKey);
   end;
   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
   begin
-    result := false;
-    Exit;
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifyingRecovery);
   end;
   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
   begin
-    result := false;
+    result := TBigIntegers.AsUnsignedByteArray(t);
     Exit;
     Exit;
   end;
   end;
 
 
-  x := P.AffineXCoord.ToBigInteger();
-  t := r.Subtract(x).&Mod(n);
-
-  result := t.Equals(e);
+  result := Nil;
 end;
 end;
 
 
 end.
 end.

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

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

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

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

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

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

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

@@ -118,6 +118,7 @@ type
 
 
     function Trace(): Int32;
     function Trace(): Int32;
     function HalfTrace(): IECFieldElement;
     function HalfTrace(): IECFieldElement;
+    function HasFastTrace(): Boolean;
   end;
   end;
 
 
 type
 type
@@ -252,6 +253,9 @@ type
     function ScaleX(const scale: IECFieldElement): IECPoint;
     function ScaleX(const scale: IECFieldElement): IECPoint;
     function ScaleY(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(): TCryptoLibByteArray; overload;
     function GetEncoded(compressed: Boolean): TCryptoLibByteArray; overload;
     function GetEncoded(compressed: Boolean): TCryptoLibByteArray; overload;
 
 
@@ -591,11 +595,24 @@ type
     ['{A1839961-4FBF-42EF-BF8B-6084064A05C1}']
     ['{A1839961-4FBF-42EF-BF8B-6084064A05C1}']
     function GetSize: Int32;
     function GetSize: Int32;
     function Lookup(index: Int32): IECPoint;
     function Lookup(index: Int32): IECPoint;
+    function LookupVar(index: Int32): IECPoint;
     property Size: Int32 read GetSize;
     property Size: Int32 read GetSize;
   end;
   end;
 
 
 type
 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}']
     ['{094881EB-24A6-41A3-BAD6-D6DAB13DD17D}']
 
 
   end;
   end;
@@ -607,7 +624,7 @@ type
   end;
   end;
 
 
 type
 type
-  IDefaultF2mLookupTable = interface(IECLookupTable)
+  IDefaultF2mLookupTable = interface(IAbstractECLookupTable)
     ['{0C019049-9839-4322-BAF5-8E5D39BC426D}']
     ['{0C019049-9839-4322-BAF5-8E5D39BC426D}']
 
 
   end;
   end;

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

@@ -30,6 +30,8 @@ type
   IECNRSigner = interface(IDsaExt)
   IECNRSigner = interface(IDsaExt)
     ['{C136F005-404E-4022-886E-DE5EFCECFF9C}']
     ['{C136F005-404E-4022-886E-DE5EFCECFF9C}']
 
 
+    function GetRecoveredMessage(const r, s: TBigInteger): TCryptoLibByteArray;
+
   end;
   end;
 
 
 implementation
 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}
 {$I ..\Include\CryptoLib.inc}
 
 
@@ -23,11 +23,11 @@ interface
 
 
 uses
 uses
   ClpBigInteger,
   ClpBigInteger,
-  ClpIAbstractECMultiplier;
+  ClpIGlvEndomorphism;
 
 
 type
 type
-  IGlvMultiplier = interface(IAbstractECMultiplier)
-    ['{F54D54F5-F544-421B-89FC-1D8058FB8F33}']
+  IGlvTypeAEndomorphism = interface(IGlvEndomorphism)
+    ['{961A1588-7D37-46C5-BC67-F71063641B42}']
 
 
   end;
   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}
 {$I ..\Include\CryptoLib.inc}
 
 
@@ -23,24 +23,21 @@ interface
 
 
 uses
 uses
   ClpBigInteger,
   ClpBigInteger,
-  ClpIAbstractECMultiplier;
+  ClpIScalarSplitParameters,
+  ClpCryptoLibTypes;
 
 
 type
 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;
   end;
 
 

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

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

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

@@ -23,6 +23,7 @@ interface
 
 
 uses
 uses
   ClpBigInteger,
   ClpBigInteger,
+  ClpIScalarSplitParameters,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
 type
 type
@@ -30,25 +31,13 @@ type
   IGlvTypeBParameters = interface(IInterface)
   IGlvTypeBParameters = interface(IInterface)
     ['{089AC2AB-15A1-47F5-BED0-C09EA77BECB9}']
     ['{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 GetLambda: TBigInteger;
     function GetBeta: 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 lambda: TBigInteger read GetLambda;
     property beta: TBigInteger read GetBeta;
     property beta: TBigInteger read GetBeta;
-    property bits: Int32 read GetBits;
+    property splitParams: IScalarSplitParameters read GetSplitParams;
 
 
   end;
   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}
 {$I ..\Include\CryptoLib.inc}
 
 
@@ -23,9 +23,36 @@ interface
 
 
 uses
 uses
   ClpBigInteger,
   ClpBigInteger,
-  ClpIECC,
   ClpIZTauElement,
   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
 type
   IWTauNafMultiplier = interface(IAbstractECMultiplier)
   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}
 {$I ..\Include\CryptoLib.inc}
 
 
 interface
 interface
 
 
 uses
 uses
-  ClpIAbstractECMultiplier;
+  ClpIECC;
 
 
 type
 type
-  IFixedPointCombMultiplier = interface(IAbstractECMultiplier)
-    ['{A3345E31-4D5C-4442-9C3D-ACC7F6DA4A14}']
+  IScaleXNegateYPointMap = interface(IECPointMap)
+
+    ['{D4FF6900-B627-45AB-8066-00E763213CE5}']
 
 
   end;
   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}
 {$I ..\Include\CryptoLib.inc}
 
 
 interface
 interface
 
 
 uses
 uses
-  ClpBigInteger,
   ClpIECC;
   ClpIECC;
 
 
 type
 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;
   end;
 
 

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -37,12 +37,30 @@ type
     function GetTwice: IECPoint;
     function GetTwice: IECPoint;
     procedure SetTwice(const Value: 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
     property PreComp: TCryptoLibGenericArray<IECPoint> read GetPreComp
       write SetPreComp;
       write SetPreComp;
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
       write SetPreCompNeg;
       write SetPreCompNeg;
     property Twice: IECPoint read GetTwice write SetTwice;
     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;
   end;
 
 
 implementation
 implementation

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

@@ -25,17 +25,18 @@ uses
   SysUtils,
   SysUtils,
   Math,
   Math,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
-  ClpBits,
   ClpBigInteger,
   ClpBigInteger,
-  ClpWNafPreCompInfo,
-  ClpIPolynomialExtensionField,
-  ClpIGlvEndomorphism,
-  ClpIWNafPreCompInfo,
-  ClpIPreCompInfo,
-  ClpIPreCompCallBack,
+  ClpBits,
+  ClpNat,
   ClpIECC,
   ClpIECC,
-  ClpECCurveConstants,
-  ClpIFiniteField;
+  ClpECCompUtilities,
+  ClpIWNafPreCompInfo,
+  ClpIFiniteField,
+  ClpIFixedPointPreCompInfo,
+  ClpIGlvEndomorphism,
+  ClpIMultipliers,
+  ClpMultipliers,
+  ClpIPolynomialExtensionField;
 
 
 resourcestring
 resourcestring
   SInvalidArray =
   SInvalidArray =
@@ -43,160 +44,8 @@ resourcestring
   SInvalidPointLocation = 'Point Must be on the Same Curve';
   SInvalidPointLocation = 'Point Must be on the Same Curve';
   SInvalidPoint = 'Invalid Point, "P"';
   SInvalidPoint = 'Invalid Point, "P"';
   SInvalidResult = 'Invalid Result';
   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
 type
   TECAlgorithms = class sealed(TObject)
   TECAlgorithms = class sealed(TObject)
@@ -212,6 +61,10 @@ type
       const infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
       const infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
       const wnafs: TCryptoLibMatrixByteArray): IECPoint; overload; static;
       const wnafs: TCryptoLibMatrixByteArray): IECPoint; overload; static;
 
 
+    class function ImplShamirsTrickFixedPoint(const p: IECPoint;
+      const k: TBigInteger; const q: IECPoint; const l: TBigInteger)
+      : IECPoint; static;
+
   public
   public
     class function IsF2mCurve(const c: IECCurve): Boolean; static;
     class function IsF2mCurve(const c: IECCurve): Boolean; static;
     class function IsF2mField(const field: IFiniteField): Boolean; static;
     class function IsF2mField(const field: IFiniteField): Boolean; static;
@@ -222,7 +75,7 @@ type
       const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint; static;
       const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint; static;
 
 
     class function SumOfTwoMultiplies(const p: IECPoint; const a: TBigInteger;
     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
     // * "Shamir's Trick", originally due to E. G. Straus
@@ -243,7 +96,7 @@ type
     // * 9: return R
     // * 9: return R
     // */
     // */
     class function ShamirsTrick(const p: IECPoint; const k: TBigInteger;
     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)
     class function ImportPoint(const c: IECCurve; const p: IECPoint)
       : IECPoint; static;
       : IECPoint; static;
@@ -277,14 +130,13 @@ type
       : IECPoint; static;
       : IECPoint; static;
 
 
     class function ImplShamirsTrickJsf(const p: IECPoint; const k: TBigInteger;
     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;
     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
     class function ImplSumOfMultiplies
       (const ps: TCryptoLibGenericArray<IECPoint>;
       (const ps: TCryptoLibGenericArray<IECPoint>;
@@ -296,8 +148,8 @@ type
       const ks: TCryptoLibGenericArray<TBigInteger>;
       const ks: TCryptoLibGenericArray<TBigInteger>;
       const glvEndomorphism: IGlvEndomorphism): IECPoint; static;
       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;
       const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint;
       overload; static;
       overload; static;
 
 
@@ -341,33 +193,124 @@ begin
   result := p;
   result := p;
 end;
 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;
 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
 var
   Curve: IECCurve;
   Curve: IECCurve;
-  infinity, R: IECPoint;
+  Infinity, R: IECPoint;
   PaddQ, PsubQ: IECPoint;
   PaddQ, PsubQ: IECPoint;
   points, table: TCryptoLibGenericArray<IECPoint>;
   points, table: TCryptoLibGenericArray<IECPoint>;
   jsf: TCryptoLibByteArray;
   jsf: TCryptoLibByteArray;
   i, jsfi, kDigit, lDigit, index: Int32;
   i, jsfi, kDigit, lDigit, index: Int32;
 begin
 begin
   Curve := p.Curve;
   Curve := p.Curve;
-  infinity := Curve.infinity;
+  Infinity := Curve.Infinity;
 
 
   // TODO conjugate co-Z addition (ZADDC) can return both of these
   // 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);
   Curve.NormalizeAll(points);
 
 
   table := TCryptoLibGenericArray<IECPoint>.Create(points[3].Negate(),
   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]);
     points[0], points[1], points[2], points[3]);
 
 
   jsf := TWNafUtilities.GenerateJsf(k, l);
   jsf := TWNafUtilities.GenerateJsf(k, l);
 
 
-  R := infinity;
+  R := Infinity;
 
 
   i := System.length(jsf);
   i := System.length(jsf);
   System.Dec(i);
   System.Dec(i);
@@ -387,13 +330,12 @@ begin
   result := R;
   result := R;
 end;
 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
 var
   negK, negL: Boolean;
   negK, negL: Boolean;
-  width: Int32;
-  Q: IECPoint;
+  minWidth, widthP, widthQ: Int32;
+  q: IECPoint;
   infoP, infoQ: IWNafPreCompInfo;
   infoP, infoQ: IWNafPreCompInfo;
   preCompP, preCompQ, preCompNegP, preCompNegQ
   preCompP, preCompQ, preCompNegP, preCompNegQ
     : TCryptoLibGenericArray<IECPoint>;
     : TCryptoLibGenericArray<IECPoint>;
@@ -408,12 +350,15 @@ begin
   LK := LK.Abs();
   LK := LK.Abs();
   LL := LL.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
   case negK of
     true:
     true:
@@ -443,8 +388,8 @@ begin
       preCompNegQ := infoQ.PreCompNeg
       preCompNegQ := infoQ.PreCompNeg
   end;
   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,
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
     preCompNegQ, wnafQ);
     preCompNegQ, wnafQ);
@@ -457,29 +402,48 @@ begin
 end;
 end;
 
 
 class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint;
 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
 var
   negK, negL: Boolean;
   negK, negL: Boolean;
-  widthP, widthQ: Int32;
+  minWidthP, minWidthQ, widthP, widthQ, combSize: Int32;
   infoP, infoQ: IWNafPreCompInfo;
   infoP, infoQ: IWNafPreCompInfo;
   preCompP, preCompQ, preCompNegP, preCompNegQ
   preCompP, preCompQ, preCompNegP, preCompNegQ
     : TCryptoLibGenericArray<IECPoint>;
     : TCryptoLibGenericArray<IECPoint>;
   wnafP, wnafQ: TCryptoLibByteArray;
   wnafP, wnafQ: TCryptoLibByteArray;
-  LK, LL: TBigInteger;
+  kAbs, lAbs: TBigInteger;
+  c: IECCurve;
 begin
 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
   if negK then
   begin
   begin
@@ -517,8 +481,8 @@ begin
     preCompNegQ := infoQ.PreCompNeg
     preCompNegQ := infoQ.PreCompNeg
   end;
   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,
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
     preCompNegQ, wnafQ);
     preCompNegQ, wnafQ);
@@ -536,15 +500,15 @@ class function TECAlgorithms.ImplShamirsTrickWNaf(const preCompP,
 var
 var
   len, zeroes, i, wiP, wiQ, nP, nQ: Int32;
   len, zeroes, i, wiP, wiQ, nP, nQ: Int32;
   Curve: IECCurve;
   Curve: IECCurve;
-  infinity, R, point: IECPoint;
+  Infinity, R, point: IECPoint;
   tableP, tableQ: TCryptoLibGenericArray<IECPoint>;
   tableP, tableQ: TCryptoLibGenericArray<IECPoint>;
 begin
 begin
-  len := Math.Max(System.length(wnafP), System.length(wnafQ));
+  len := Max(System.length(wnafP), System.length(wnafQ));
 
 
   Curve := preCompP[0].Curve;
   Curve := preCompP[0].Curve;
-  infinity := Curve.infinity;
+  Infinity := Curve.Infinity;
 
 
-  R := infinity;
+  R := Infinity;
   zeroes := 0;
   zeroes := 0;
 
 
   i := len - 1;
   i := len - 1;
@@ -576,7 +540,7 @@ begin
       continue;
       continue;
     end;
     end;
 
 
-    point := infinity;
+    point := Infinity;
     if (wiP <> 0) then
     if (wiP <> 0) then
     begin
     begin
       nP := System.Abs(wiP);
       nP := System.Abs(wiP);
@@ -626,17 +590,19 @@ begin
   result := R;
   result := R;
 end;
 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;
   const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint;
 var
 var
   halfCount, fullCount: Int32;
   halfCount, fullCount: Int32;
   negs: TCryptoLibBooleanArray;
   negs: TCryptoLibBooleanArray;
   infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
   infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
+  infoP, infoQ: IWNafPreCompInfo;
   wnafs: TCryptoLibMatrixByteArray;
   wnafs: TCryptoLibMatrixByteArray;
-  i, j0, j1, width: Int32;
+  i, j0, j1, minWidth, widthP, widthQ: Int32;
   kj0, kj1: TBigInteger;
   kj0, kj1: TBigInteger;
-  p, Q: IECPoint;
+  p, q: IECPoint;
+  pointMap: IECPointMap;
 begin
 begin
   halfCount := System.length(ps);
   halfCount := System.length(ps);
   fullCount := halfCount shl 1;
   fullCount := halfCount shl 1;
@@ -644,6 +610,8 @@ begin
   System.SetLength(infos, fullCount);
   System.SetLength(infos, fullCount);
   System.SetLength(wnafs, fullCount);
   System.SetLength(wnafs, fullCount);
 
 
+  pointMap := endomorphism.pointMap;
+
   for i := 0 to System.Pred(halfCount) do
   for i := 0 to System.Pred(halfCount) do
   begin
   begin
     j0 := i shl 1;
     j0 := i shl 1;
@@ -656,15 +624,21 @@ begin
     negs[j1] := kj1.SignValue < 0;
     negs[j1] := kj1.SignValue < 0;
     kj1 := kj1.Abs();
     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];
     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;
   end;
 
 
   result := ImplSumOfMultiplies(negs, infos, wnafs);
   result := ImplSumOfMultiplies(negs, infos, wnafs);
@@ -681,8 +655,9 @@ class function TECAlgorithms.ImplSumOfMultiplies
   (const ps: TCryptoLibGenericArray<IECPoint>;
   (const ps: TCryptoLibGenericArray<IECPoint>;
   const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint;
   const ks: TCryptoLibGenericArray<TBigInteger>): IECPoint;
 var
 var
-  count, i, width: Int32;
+  count, i, width, minWidth: Int32;
   negs: TCryptoLibBooleanArray;
   negs: TCryptoLibBooleanArray;
+  info: IWNafPreCompInfo;
   infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
   infos: TCryptoLibGenericArray<IWNafPreCompInfo>;
   wnafs: TCryptoLibMatrixByteArray;
   wnafs: TCryptoLibMatrixByteArray;
   ki: TBigInteger;
   ki: TBigInteger;
@@ -700,8 +675,11 @@ begin
     negs[i] := ki.SignValue < 0;
     negs[i] := ki.SignValue < 0;
     ki := ki.Abs();
     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);
     wnafs[i] := TWNafUtilities.GenerateWindowNaf(width, ki);
   end;
   end;
 
 
@@ -721,9 +699,9 @@ class function TECAlgorithms.ImplSumOfMultiplies
   const wnafs: TCryptoLibMatrixByteArray): IECPoint;
   const wnafs: TCryptoLibMatrixByteArray): IECPoint;
 var
 var
   len, count, zeroes: Int32;
   len, count, zeroes: Int32;
-  i, J, wi, n: Int32;
+  i, j, wi, n: Int32;
   Curve: IECCurve;
   Curve: IECCurve;
-  infinity, R, point: IECPoint;
+  Infinity, R, point: IECPoint;
   wnaf: TCryptoLibByteArray;
   wnaf: TCryptoLibByteArray;
   info: IWNafPreCompInfo;
   info: IWNafPreCompInfo;
   table: TCryptoLibGenericArray<IECPoint>;
   table: TCryptoLibGenericArray<IECPoint>;
@@ -737,19 +715,19 @@ begin
   end;
   end;
 
 
   Curve := infos[0].PreComp[0].Curve;
   Curve := infos[0].PreComp[0].Curve;
-  infinity := Curve.infinity;
+  Infinity := Curve.Infinity;
 
 
-  R := infinity;
+  R := Infinity;
   zeroes := 0;
   zeroes := 0;
 
 
   i := len - 1;
   i := len - 1;
   while (i >= 0) do
   while (i >= 0) do
   begin
   begin
-    point := infinity;
+    point := Infinity;
 
 
-    for J := 0 to System.Pred(count) do
+    for j := 0 to System.Pred(count) do
     begin
     begin
-      wnaf := wnafs[J];
+      wnaf := wnafs[j];
       if i < System.length(wnaf) then
       if i < System.length(wnaf) then
       begin
       begin
         wi := Int32(ShortInt(wnaf[i]));
         wi := Int32(ShortInt(wnaf[i]));
@@ -762,8 +740,8 @@ begin
       if (wi <> 0) then
       if (wi <> 0) then
       begin
       begin
         n := System.Abs(wi);
         n := System.Abs(wi);
-        info := infos[J];
-        if (wi < 0 = negs[J]) then
+        info := infos[j];
+        if (wi < 0 = negs[j]) then
         begin
         begin
           table := info.PreComp;
           table := info.PreComp;
         end
         end
@@ -776,7 +754,7 @@ begin
       end;
       end;
     end;
     end;
 
 
-    if (point = infinity) then
+    if (point = Infinity) then
     begin
     begin
       System.Inc(zeroes);
       System.Inc(zeroes);
       System.Dec(i);
       System.Dec(i);
@@ -809,11 +787,10 @@ class function TECAlgorithms.ImplSumOfMultipliesGlv
   const glvEndomorphism: IGlvEndomorphism): IECPoint;
   const glvEndomorphism: IGlvEndomorphism): IECPoint;
 var
 var
   n: TBigInteger;
   n: TBigInteger;
-  len, i, J: Int32;
+  len, i, j: Int32;
   &abs, ab: TCryptoLibGenericArray<TBigInteger>;
   &abs, ab: TCryptoLibGenericArray<TBigInteger>;
-  pointMap: IECPointMap;
   pqs: TCryptoLibGenericArray<IECPoint>;
   pqs: TCryptoLibGenericArray<IECPoint>;
-  p, Q: IECPoint;
+  p, q: IECPoint;
 begin
 begin
   n := ps[0].Curve.Order;
   n := ps[0].Curve.Order;
 
 
@@ -822,40 +799,39 @@ begin
   System.SetLength(Abs, len shl 1);
   System.SetLength(Abs, len shl 1);
 
 
   i := 0;
   i := 0;
-  J := 0;
+  j := 0;
 
 
   while (i < len) do
   while (i < len) do
   begin
   begin
     ab := glvEndomorphism.DecomposeScalar(ks[i].&Mod(n));
     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);
     System.Inc(i);
   end;
   end;
 
 
-  pointMap := glvEndomorphism.pointMap;
   if (glvEndomorphism.HasEfficientPointMap) then
   if (glvEndomorphism.HasEfficientPointMap) then
   begin
   begin
-    result := TECAlgorithms.ImplSumOfMultiplies(ps, pointMap, Abs);
+    result := TECAlgorithms.ImplSumOfMultiplies(glvEndomorphism, ps, Abs);
     Exit;
     Exit;
   end;
   end;
 
 
   System.SetLength(pqs, len shl 1);
   System.SetLength(pqs, len shl 1);
 
 
   i := 0;
   i := 0;
-  J := 0;
+  j := 0;
 
 
   while (i < len) do
   while (i < len) do
   begin
   begin
     p := ps[i];
     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);
     System.Inc(i);
   end;
   end;
 
 
@@ -903,7 +879,7 @@ class procedure TECAlgorithms.MontgomeryTrick
   const scale: IECFieldElement);
   const scale: IECFieldElement);
 var
 var
   c: TCryptoLibGenericArray<IECFieldElement>;
   c: TCryptoLibGenericArray<IECFieldElement>;
-  i, J: Int32;
+  i, j: Int32;
   u, tmp: IECFieldElement;
   u, tmp: IECFieldElement;
 begin
 begin
   // /*
   // /*
@@ -935,10 +911,10 @@ begin
 
 
   while (i > 0) do
   while (i > 0) do
   begin
   begin
-    J := off + i;
+    j := off + i;
     System.Dec(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);
     u := u.Multiply(tmp);
   end;
   end;
 
 
@@ -955,18 +931,18 @@ class function TECAlgorithms.ReferenceMultiply(const p: IECPoint;
   const k: TBigInteger): IECPoint;
   const k: TBigInteger): IECPoint;
 var
 var
   x: TBigInteger;
   x: TBigInteger;
-  Q, LP: IECPoint;
+  q, LP: IECPoint;
   t, i: Int32;
   t, i: Int32;
 begin
 begin
   LP := p;
   LP := p;
   x := k.Abs();
   x := k.Abs();
-  Q := LP.Curve.infinity;
+  q := LP.Curve.Infinity;
   t := x.BitLength;
   t := x.BitLength;
   if (t > 0) then
   if (t > 0) then
   begin
   begin
     if (x.TestBit(0)) then
     if (x.TestBit(0)) then
     begin
     begin
-      Q := LP;
+      q := LP;
     end;
     end;
     i := 1;
     i := 1;
     while (i < t) do
     while (i < t) do
@@ -974,7 +950,7 @@ begin
       LP := LP.Twice();
       LP := LP.Twice();
       if (x.TestBit(i)) then
       if (x.TestBit(i)) then
       begin
       begin
-        Q := Q.Add(LP);
+        q := q.Add(LP);
       end;
       end;
       System.Inc(i);
       System.Inc(i);
     end;
     end;
@@ -983,23 +959,23 @@ begin
 
 
   if k.SignValue < 0 then
   if k.SignValue < 0 then
   begin
   begin
-    result := Q.Negate();
+    result := q.Negate();
   end
   end
   else
   else
   begin
   begin
-    result := Q;
+    result := q;
   end;
   end;
 
 
 end;
 end;
 
 
 class function TECAlgorithms.ShamirsTrick(const p: IECPoint;
 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
 var
   cp: IECCurve;
   cp: IECCurve;
   LQ: IECPoint;
   LQ: IECPoint;
 begin
 begin
   cp := p.Curve;
   cp := p.Curve;
-  LQ := Q;
+  LQ := q;
   LQ := ImportPoint(cp, LQ);
   LQ := ImportPoint(cp, LQ);
 
 
   result := ImplCheckResult(ImplShamirsTrickJsf(p, k, LQ, l));
   result := ImplCheckResult(ImplShamirsTrickJsf(p, k, LQ, l));
@@ -1060,7 +1036,7 @@ begin
 end;
 end;
 
 
 class function TECAlgorithms.SumOfTwoMultiplies(const p: IECPoint;
 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
 var
   cp: IECCurve;
   cp: IECCurve;
   f2mCurve: IAbstractF2mCurve;
   f2mCurve: IAbstractF2mCurve;
@@ -1068,7 +1044,7 @@ var
   LQ: IECPoint;
   LQ: IECPoint;
 begin
 begin
   cp := p.Curve;
   cp := p.Curve;
-  LQ := Q;
+  LQ := q;
   LQ := ImportPoint(cp, LQ);
   LQ := ImportPoint(cp, LQ);
 
 
   // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
   // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
@@ -1090,711 +1066,4 @@ begin
   result := ImplCheckResult(ImplShamirsTrickWNaf(p, a, LQ, b));
   result := ImplCheckResult(ImplShamirsTrickWNaf(p, a, LQ, b));
 end;
 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.
 end.

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

@@ -37,9 +37,7 @@ uses
   ClpIGlvEndomorphism,
   ClpIGlvEndomorphism,
   ClpECAlgorithms,
   ClpECAlgorithms,
   ClpLongArray,
   ClpLongArray,
-  ClpGlvMultiplier,
-  ClpWNafL2RMultiplier,
-  ClpWTauNafMultiplier,
+  ClpMultipliers,
   ClpFiniteFields,
   ClpFiniteFields,
   ClpSetWeakRef,
   ClpSetWeakRef,
   ClpECCurveConstants,
   ClpECCurveConstants,
@@ -95,6 +93,7 @@ resourcestring
   SNotProjectiveCoordSystem = 'Not a Projective Coordinate System';
   SNotProjectiveCoordSystem = 'Not a Projective Coordinate System';
   SCannotBeNegative = 'Cannot be Negative, "e"';
   SCannotBeNegative = 'Cannot be Negative, "e"';
   SNilFieldElement = 'Exactly one of the Field Elements is Nil';
   SNilFieldElement = 'Exactly one of the Field Elements is Nil';
+  SUnsupportedOperation = 'Constant-time Lookup not Supported';
 
 
 type
 type
   TECFieldElement = class abstract(TInterfacedObject, IECFieldElement)
   TECFieldElement = class abstract(TInterfacedObject, IECFieldElement)
@@ -260,6 +259,7 @@ type
   public
   public
     function Trace(): Int32; virtual;
     function Trace(): Int32; virtual;
     function HalfTrace(): IECFieldElement; virtual;
     function HalfTrace(): IECFieldElement; virtual;
+    function HasFastTrace(): Boolean; virtual;
 
 
   end;
   end;
 
 
@@ -691,20 +691,61 @@ type
   end;
   end;
 
 
 type
 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
   strict private
   var
   var
     Fm_outer: IECCurve;
     Fm_outer: IECCurve;
     Fm_table: TCryptoLibByteArray;
     Fm_table: TCryptoLibByteArray;
     Fm_size: Int32;
     Fm_size: Int32;
 
 
+    function CreatePoint(const x, y: TCryptoLibByteArray): IECPoint;
+
+  strict protected
+    function GetSize: Int32; override;
+
   public
   public
     constructor Create(const outer: IECCurve; const table: TCryptoLibByteArray;
     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;
   end;
 
 
@@ -724,20 +765,24 @@ type
   end;
   end;
 
 
 type
 type
-  TDefaultF2mLookupTable = class(TInterfacedObject, IDefaultF2mLookupTable,
-    IECLookupTable)
+  TDefaultF2mLookupTable = class(TAbstractECLookupTable, IDefaultF2mLookupTable)
   strict private
   strict private
   var
   var
     Fm_outer: IF2mCurve;
     Fm_outer: IF2mCurve;
     Fm_table: TCryptoLibInt64Array;
     Fm_table: TCryptoLibInt64Array;
     Fm_size: Int32;
     Fm_size: Int32;
 
 
+    function CreatePoint(const x, y: TCryptoLibInt64Array): IECPoint;
+
+  strict protected
+    function GetSize: Int32; override;
+
   public
   public
     constructor Create(const outer: IF2mCurve;
     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;
   end;
 
 
@@ -1158,6 +1203,9 @@ type
     function ScaleX(const scale: IECFieldElement): IECPoint; virtual;
     function ScaleX(const scale: IECFieldElement): IECPoint; virtual;
     function ScaleY(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(): TCryptoLibByteArray; overload; virtual;
     function GetEncoded(compressed: Boolean): TCryptoLibByteArray; overload;
     function GetEncoded(compressed: Boolean): TCryptoLibByteArray; overload;
       virtual; abstract;
       virtual; abstract;
@@ -1400,6 +1448,9 @@ type
     function ScaleX(const scale: IECFieldElement): IECPoint; override;
     function ScaleX(const scale: IECFieldElement): IECPoint; override;
     function ScaleY(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 Subtract(const b: IECPoint): IECPoint; override;
 
 
     function Tau(): IAbstractF2mPoint; virtual;
     function Tau(): IAbstractF2mPoint; virtual;
@@ -2433,8 +2484,8 @@ end;
 
 
 function TAbstractF2mFieldElement.HalfTrace: IECFieldElement;
 function TAbstractF2mFieldElement.HalfTrace: IECFieldElement;
 var
 var
-  m, i: Int32;
-  fe, ht: IECFieldElement;
+  m, n, K, nk: Int32;
+  ht: IECFieldElement;
 begin
 begin
   m := FieldSize;
   m := FieldSize;
   if ((m and 1) = 0) then
   if ((m and 1) = 0) then
@@ -2442,34 +2493,53 @@ begin
     raise EArgumentCryptoLibException.CreateRes(@SHalfTraceUndefinedForM);
     raise EArgumentCryptoLibException.CreateRes(@SHalfTraceUndefinedForM);
   end;
   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
   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;
   result := ht;
 end;
 end;
 
 
+function TAbstractF2mFieldElement.HasFastTrace: Boolean;
+begin
+  result := false;
+
+end;
+
 function TAbstractF2mFieldElement.Trace: Int32;
 function TAbstractF2mFieldElement.Trace: Int32;
 var
 var
-  m, i: Int32;
-  fe, tr: IECFieldElement;
+  m, K, mk: Int32;
+  tr: IECFieldElement;
 begin
 begin
   m := FieldSize;
   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
   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;
   end;
 
 
   if (tr.IsZero) then
   if (tr.IsZero) then
@@ -3372,9 +3442,36 @@ end;
 function TAbstractF2mCurve.SolveQuadraticEquation(const beta: IECFieldElement)
 function TAbstractF2mCurve.SolveQuadraticEquation(const beta: IECFieldElement)
   : IECFieldElement;
   : IECFieldElement;
 var
 var
-  gamma, z, zeroElement, t, w, w2: IECFieldElement;
+  gamma, z, zeroElement, t, w, w2, r: IECFieldElement;
+  betaF2m: IAbstractF2mFieldElement;
   m, i: Int32;
   m, i: Int32;
+  fastTrace: Boolean;
 begin
 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
   if (beta.IsZero) then
   begin
   begin
     result := beta;
     result := beta;
@@ -3603,12 +3700,22 @@ end;
 { TDefaultLookupTable }
 { TDefaultLookupTable }
 
 
 constructor TDefaultLookupTable.Create(const outer: IECCurve;
 constructor TDefaultLookupTable.Create(const outer: IECCurve;
-  const table: TCryptoLibByteArray; size: Int32);
+  const table: TCryptoLibByteArray; Size: Int32);
 begin
 begin
   Inherited Create();
   Inherited Create();
   Fm_outer := outer;
   Fm_outer := outer;
   Fm_table := table;
   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;
 end;
 
 
 function TDefaultLookupTable.GetSize: Int32;
 function TDefaultLookupTable.GetSize: Int32;
@@ -3621,7 +3728,6 @@ var
   FE_BYTES, position, i, j: Int32;
   FE_BYTES, position, i, j: Int32;
   x, y: TCryptoLibByteArray;
   x, y: TCryptoLibByteArray;
   MASK: Byte;
   MASK: Byte;
-  XFieldElement, YFieldElement: IECFieldElement;
 begin
 begin
   FE_BYTES := (Fm_outer.FieldSize + 7) div 8;
   FE_BYTES := (Fm_outer.FieldSize + 7) div 8;
   System.SetLength(x, FE_BYTES);
   System.SetLength(x, FE_BYTES);
@@ -3636,41 +3742,52 @@ begin
 
 
     for j := 0 to System.Pred(FE_BYTES) do
     for j := 0 to System.Pred(FE_BYTES) do
     begin
     begin
-
       x[j] := x[j] xor Byte(Fm_table[position + j] and MASK);
       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);
       y[j] := y[j] xor Byte(Fm_table[position + FE_BYTES + j] and MASK);
     end;
     end;
     position := position + (FE_BYTES * 2);
     position := position + (FE_BYTES * 2);
   end;
   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;
 end;
 
 
 { TDefaultF2mLookupTable }
 { TDefaultF2mLookupTable }
 
 
 constructor TDefaultF2mLookupTable.Create(const outer: IF2mCurve;
 constructor TDefaultF2mLookupTable.Create(const outer: IF2mCurve;
-  const table: TCryptoLibInt64Array; size: Int32);
+  const table: TCryptoLibInt64Array; Size: Int32);
 begin
 begin
   Inherited Create();
   Inherited Create();
   Fm_outer := outer;
   Fm_outer := outer;
   Fm_table := table;
   Fm_table := table;
-  Fm_size := size;
-end;
-
-function TDefaultF2mLookupTable.GetSize: Int32;
-begin
-  result := Fm_size;
+  Fm_size := Size;
 end;
 end;
 
 
-function TDefaultF2mLookupTable.Lookup(index: Int32): IECPoint;
+function TDefaultF2mLookupTable.CreatePoint(const x, y: TCryptoLibInt64Array)
+  : IECPoint;
 var
 var
-  FE_LONGS, position, m, i, j: Int32;
-  ks: TCryptoLibInt32Array;
-  x, y: TCryptoLibInt64Array;
-  MASK: Int64;
   XFieldElement, YFieldElement: IECFieldElement;
   XFieldElement, YFieldElement: IECFieldElement;
+  m: Int32;
+  ks: TCryptoLibInt32Array;
 begin
 begin
   m := Fm_outer.m;
   m := Fm_outer.m;
   if Fm_outer.IsTrinomial() then
   if Fm_outer.IsTrinomial() then
@@ -3682,6 +3799,22 @@ begin
     ks := TCryptoLibInt32Array.Create(Fm_outer.k1, Fm_outer.k2, Fm_outer.k3);
     ks := TCryptoLibInt32Array.Create(Fm_outer.k1, Fm_outer.k2, Fm_outer.k3);
   end;
   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;
   FE_LONGS := (Fm_outer.m + 63) div 64;
   System.SetLength(x, FE_LONGS);
   System.SetLength(x, FE_LONGS);
   System.SetLength(y, FE_LONGS);
   System.SetLength(y, FE_LONGS);
@@ -3695,16 +3828,33 @@ begin
 
 
     for j := 0 to System.Pred(FE_LONGS) do
     for j := 0 to System.Pred(FE_LONGS) do
     begin
     begin
-
       x[j] := x[j] xor (Fm_table[position + j] and MASK);
       x[j] := x[j] xor (Fm_table[position + j] and MASK);
       y[j] := y[j] xor (Fm_table[position + FE_LONGS + j] and MASK);
       y[j] := y[j] xor (Fm_table[position + FE_LONGS + j] and MASK);
     end;
     end;
     position := position + (FE_LONGS * 2);
     position := position + (FE_LONGS * 2);
   end;
   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;
 end;
 
 
 { TECPoint }
 { TECPoint }
@@ -3798,6 +3948,19 @@ begin
   end;
   end;
 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;
 function TECPoint.ScaleY(const scale: IECFieldElement): IECPoint;
 begin
 begin
   if IsInfinity then
   if IsInfinity then
@@ -3811,6 +3974,19 @@ begin
   end;
   end;
 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
 procedure TECPoint.SetpreCompTable(const Value
   : TDictionary<String, IPreCompInfo>);
   : TDictionary<String, IPreCompInfo>);
 begin
 begin
@@ -6201,21 +6377,23 @@ function TAbstractF2mPoint.SatisfiesOrder: Boolean;
 var
 var
   Cofactor: TBigInteger;
   Cofactor: TBigInteger;
   n: IECPoint;
   n: IECPoint;
-  x, rhs, lambda, w, t: IECFieldElement;
+  x, rhs, L, t, y: IECFieldElement;
   Lcurve: IECCurve;
   Lcurve: IECCurve;
 begin
 begin
   Lcurve := curve;
   Lcurve := curve;
   Cofactor := Lcurve.GetCofactor();
   Cofactor := Lcurve.GetCofactor();
   if (TBigInteger.Two.Equals(Cofactor)) then
   if (TBigInteger.Two.Equals(Cofactor)) then
   begin
   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();
     n := Normalize();
     x := n.AffineXCoord;
     x := n.AffineXCoord;
     rhs := x.Add(Lcurve.a);
     rhs := x.Add(Lcurve.a);
-    result := (rhs as IAbstractF2mFieldElement).Trace() = 0;
+    result := (x as IAbstractF2mFieldElement).Trace() <> 0;
     Exit;
     Exit;
   end;
   end;
   if (TBigInteger.Four.Equals(Cofactor)) then
   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
     // * 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.
     // * (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();
     n := Normalize();
     x := n.AffineXCoord;
     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
     begin
       result := false;
       result := false;
       Exit;
       Exit;
     end;
     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;
     Exit;
   end;
   end;
 
 
@@ -6296,6 +6486,12 @@ begin
 
 
 end;
 end;
 
 
+function TAbstractF2mPoint.ScaleXNegateY(const scale: IECFieldElement)
+  : IECPoint;
+begin
+  result := ScaleX(scale);
+end;
+
 function TAbstractF2mPoint.ScaleY(const scale: IECFieldElement): IECPoint;
 function TAbstractF2mPoint.ScaleY(const scale: IECFieldElement): IECPoint;
 var
 var
   Lx, L, L2: IECFieldElement;
   Lx, L, L2: IECFieldElement;
@@ -6327,6 +6523,12 @@ begin
 
 
 end;
 end;
 
 
+function TAbstractF2mPoint.ScaleYNegateX(const scale: IECFieldElement)
+  : IECPoint;
+begin
+  result := ScaleY(scale);
+end;
+
 function TAbstractF2mPoint.Subtract(const b: IECPoint): IECPoint;
 function TAbstractF2mPoint.Subtract(const b: IECPoint): IECPoint;
 begin
 begin
   if (b.IsInfinity) then
   if (b.IsInfinity) then
@@ -6480,4 +6682,41 @@ begin
   result := info;
   result := info;
 end;
 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.
 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
   strict private
 
 
   type
   type
-    TCurve25519LookupTable = class sealed(TInterfacedObject,
-      ICurve25519LookupTable, IECLookupTable)
+    TCurve25519LookupTable = class sealed(TAbstractECLookupTable,
+      ICurve25519LookupTable)
 
 
     strict private
     strict private
     var
     var
@@ -246,16 +246,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
       Fm_size: Int32;
 
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
 
     public
     public
 
 
       constructor Create(const outer: ICurve25519;
       constructor Create(const outer: ICurve25519;
         const table: TCryptoLibUInt32Array; size: Int32);
         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;
     end;
 
 
@@ -1239,13 +1242,13 @@ begin
   Fm_infinity := TCurve25519Point.Create(Self as IECCurve, Nil, Nil);
   Fm_infinity := TCurve25519Point.Create(Self as IECCurve, Nil, Nil);
 
 
   Fm_a := FromBigInteger(TBigInteger.Create(1,
   Fm_a := FromBigInteger(TBigInteger.Create(1,
-    THex.Decode
+    THex.decode
     ('2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144')));
     ('2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144')));
   Fm_b := FromBigInteger(TBigInteger.Create(1,
   Fm_b := FromBigInteger(TBigInteger.Create(1,
-    THex.Decode
+    THex.decode
     ('7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864')));
     ('7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864')));
   Fm_order := TBigInteger.Create(1,
   Fm_order := TBigInteger.Create(1,
-    THex.Decode
+    THex.decode
     ('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED'));
     ('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED'));
   Fm_cofactor := TBigInteger.ValueOf(8);
   Fm_cofactor := TBigInteger.ValueOf(8);
   Fm_coord := Curve25519_DEFAULT_COORDS;
   Fm_coord := Curve25519_DEFAULT_COORDS;
@@ -1333,6 +1336,26 @@ begin
   Fm_size := size;
   Fm_size := size;
 end;
 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;
 function TCurve25519.TCurve25519LookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -1361,9 +1384,25 @@ begin
     pos := pos + (CURVE25519_FE_INTS * 2);
     pos := pos + (CURVE25519_FE_INTS * 2);
   end;
   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;
 
 
 end.
 end.

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

@@ -211,8 +211,8 @@ type
   strict private
   strict private
 
 
   type
   type
-    TSecP256K1LookupTable = class sealed(TInterfacedObject,
-      ISecP256K1LookupTable, IECLookupTable)
+    TSecP256K1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecP256K1LookupTable)
 
 
     strict private
     strict private
     var
     var
@@ -220,16 +220,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
       Fm_size: Int32;
 
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
 
     public
     public
 
 
       constructor Create(const outer: ISecP256K1Curve;
       constructor Create(const outer: ISecP256K1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
         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;
     end;
 
 
@@ -1126,6 +1129,21 @@ begin
   Fm_size := size;
   Fm_size := size;
 end;
 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;
 function TSecP256K1Curve.TSecP256K1LookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -1154,9 +1172,26 @@ begin
     pos := pos + (SECP256K1_FE_INTS * 2);
     pos := pos + (SECP256K1_FE_INTS * 2);
   end;
   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;
 
 
 end.
 end.

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

@@ -212,8 +212,8 @@ type
   strict private
   strict private
 
 
   type
   type
-    TSecP256R1LookupTable = class sealed(TInterfacedObject,
-      ISecP256R1LookupTable, IECLookupTable)
+    TSecP256R1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecP256R1LookupTable)
 
 
     strict private
     strict private
     var
     var
@@ -221,16 +221,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
       Fm_size: Int32;
 
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
 
     public
     public
 
 
       constructor Create(const outer: ISecP256R1Curve;
       constructor Create(const outer: ISecP256R1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
         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;
     end;
 
 
@@ -1269,6 +1272,21 @@ begin
   Fm_size := size;
   Fm_size := size;
 end;
 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;
 function TSecP256R1Curve.TSecP256R1LookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -1297,9 +1315,26 @@ begin
     pos := pos + (SECP256R1_FE_INTS * 2);
     pos := pos + (SECP256R1_FE_INTS * 2);
   end;
   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;
 
 
 end.
 end.

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

@@ -210,8 +210,8 @@ type
   strict private
   strict private
 
 
   type
   type
-    TSecP384R1LookupTable = class sealed(TInterfacedObject,
-      ISecP384R1LookupTable, IECLookupTable)
+    TSecP384R1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecP384R1LookupTable)
 
 
     strict private
     strict private
     var
     var
@@ -219,16 +219,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
       Fm_size: Int32;
 
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
 
     public
     public
 
 
       constructor Create(const outer: ISecP384R1Curve;
       constructor Create(const outer: ISecP384R1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
         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;
     end;
 
 
@@ -1277,6 +1280,21 @@ begin
   Fm_size := size;
   Fm_size := size;
 end;
 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;
 function TSecP384R1Curve.TSecP384R1LookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -1305,9 +1323,26 @@ begin
     pos := pos + (SECP384R1_FE_INTS * 2);
     pos := pos + (SECP384R1_FE_INTS * 2);
   end;
   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;
 
 
 end.
 end.

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

@@ -207,7 +207,7 @@ type
   strict private
   strict private
 
 
   type
   type
-    TSecP521R1LookupTable = class sealed(TInterfacedObject,
+    TSecP521R1LookupTable = class sealed(TAbstractECLookupTable,
       ISecP521R1LookupTable, IECLookupTable)
       ISecP521R1LookupTable, IECLookupTable)
 
 
     strict private
     strict private
@@ -216,16 +216,19 @@ type
       Fm_table: TCryptoLibUInt32Array;
       Fm_table: TCryptoLibUInt32Array;
       Fm_size: Int32;
       Fm_size: Int32;
 
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt32Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
 
     public
     public
 
 
       constructor Create(const outer: ISecP521R1Curve;
       constructor Create(const outer: ISecP521R1Curve;
         const table: TCryptoLibUInt32Array; size: Int32);
         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;
     end;
 
 
@@ -1070,6 +1073,21 @@ begin
   Fm_size := size;
   Fm_size := size;
 end;
 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;
 function TSecP521R1Curve.TSecP521R1LookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -1098,9 +1116,26 @@ begin
     pos := pos + (SECP521R1_FE_INTS * 2);
     pos := pos + (SECP521R1_FE_INTS * 2);
   end;
   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;
 
 
 end.
 end.

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

@@ -31,7 +31,7 @@ uses
   ClpBigInteger,
   ClpBigInteger,
   ClpArrayUtils,
   ClpArrayUtils,
   ClpIECC,
   ClpIECC,
-  ClpWTauNafMultiplier,
+  ClpMultipliers,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpECCurveConstants,
   ClpECCurveConstants,
   ClpISecT283Custom;
   ClpISecT283Custom;
@@ -60,8 +60,9 @@ type
     class procedure ImplMulw(x, y: UInt64; const z: TCryptoLibUInt64Array;
     class procedure ImplMulw(x, y: UInt64; const z: TCryptoLibUInt64Array;
       zOff: Int32); static;
       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 procedure Boot(); static;
     class constructor SecT283Field();
     class constructor SecT283Field();
@@ -71,6 +72,10 @@ type
     class procedure AddExt(const xx, yy, zz: TCryptoLibUInt64Array);
     class procedure AddExt(const xx, yy, zz: TCryptoLibUInt64Array);
       static; inline;
       static; inline;
     class procedure AddOne(const x, z: 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;
     class function FromBigInteger(const x: TBigInteger): TCryptoLibUInt64Array;
       static; inline;
       static; inline;
 
 
@@ -152,6 +157,10 @@ type
 
 
     function Trace(): Int32; override;
     function Trace(): Int32; override;
 
 
+    function HalfTrace(): IECFieldElement; override;
+
+    function HasFastTrace(): Boolean; override;
+
     function Invert(): IECFieldElement; override;
     function Invert(): IECFieldElement; override;
 
 
     /// <summary>
     /// <summary>
@@ -249,8 +258,8 @@ type
   strict private
   strict private
 
 
   type
   type
-    TSecT283K1LookupTable = class sealed(TInterfacedObject,
-      ISecT283K1LookupTable, IECLookupTable)
+    TSecT283K1LookupTable = class sealed(TAbstractECLookupTable,
+      ISecT283K1LookupTable)
 
 
     strict private
     strict private
     var
     var
@@ -258,16 +267,19 @@ type
       Fm_table: TCryptoLibUInt64Array;
       Fm_table: TCryptoLibUInt64Array;
       Fm_size: Int32;
       Fm_size: Int32;
 
 
-      function GetSize: Int32; virtual;
+      function CreatePoint(const x, y: TCryptoLibUInt64Array): IECPoint;
+
+    strict protected
+
+      function GetSize: Int32; override;
 
 
     public
     public
 
 
       constructor Create(const outer: ISecT283K1Curve;
       constructor Create(const outer: ISecT283K1Curve;
         const table: TCryptoLibUInt64Array; size: Int32);
         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;
     end;
 
 
@@ -373,6 +385,15 @@ begin
   z[4] := x[4];
   z[4] := x[4];
 end;
 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;
 class procedure TSecT283Field.Boot;
 begin
 begin
   FROOT_Z := TCryptoLibUInt64Array.Create(UInt64($0C30C30C30C30808),
   FROOT_Z := TCryptoLibUInt64Array.Create(UInt64($0C30C30C30C30808),
@@ -380,14 +401,31 @@ begin
     UInt64($0820820820820820), UInt64($2082082));
     UInt64($0820820820820820), UInt64($2082082));
 end;
 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)
 class function TSecT283Field.FromBigInteger(const x: TBigInteger)
   : TCryptoLibUInt64Array;
   : TCryptoLibUInt64Array;
-var
-  z: TCryptoLibUInt64Array;
 begin
 begin
-  z := TNat320.FromBigInteger64(x);
-  Reduce37(z, 0);
-  result := z;
+  result := TNat.FromBigInteger64(283, x);
 end;
 end;
 
 
 class procedure TSecT283Field.Multiply(const x, y, z: TCryptoLibUInt64Array);
 class procedure TSecT283Field.Multiply(const x, y, z: TCryptoLibUInt64Array);
@@ -400,14 +438,11 @@ begin
 end;
 end;
 
 
 class procedure TSecT283Field.ImplSquare(const x, zz: TCryptoLibUInt64Array);
 class procedure TSecT283Field.ImplSquare(const x, zz: TCryptoLibUInt64Array);
-var
-  i: Int32;
 begin
 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]));
   zz[8] := TInterleave.Expand32to64(UInt32(x[4]));
 end;
 end;
 
 
@@ -909,6 +944,20 @@ begin
   result := Fx;
   result := Fx;
 end;
 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;
 function TSecT283FieldElement.Invert: IECFieldElement;
 var
 var
   z: TCryptoLibUInt64Array;
   z: TCryptoLibUInt64Array;
@@ -1545,6 +1594,21 @@ begin
   Fm_size := size;
   Fm_size := size;
 end;
 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;
 function TSecT283K1Curve.TSecT283K1LookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -1573,9 +1637,26 @@ begin
     pos := pos + (SECT283K1_FE_LONGS * 2);
     pos := pos + (SECT283K1_FE_LONGS * 2);
   end;
   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;
 
 
 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,
   ClpIGlvTypeBEndomorphism,
   ClpIECC,
   ClpIECC,
   ClpIGlvTypeBParameters,
   ClpIGlvTypeBParameters,
-  ClpIGlvEndomorphism;
+  ClpIGlvEndomorphism,
+  ClpECCompUtilities;
 
 
 type
 type
   TGlvTypeBEndomorphism = class(TInterfacedObject, IECEndomorphism,
   TGlvTypeBEndomorphism = class(TInterfacedObject, IECEndomorphism,
@@ -43,13 +44,10 @@ type
     FParameters: IGlvTypeBParameters;
     FParameters: IGlvTypeBParameters;
     FPointMap: IECPointMap;
     FPointMap: IECPointMap;
 
 
-    function CalculateB(const k, g: TBigInteger; t: Int32)
-      : TBigInteger; virtual;
-
   public
   public
     constructor Create(const curve: IECCurve;
     constructor Create(const curve: IECCurve;
       const parameters: IGlvTypeBParameters);
       const parameters: IGlvTypeBParameters);
-    destructor Destroy; override;
+
     function DecomposeScalar(const k: TBigInteger)
     function DecomposeScalar(const k: TBigInteger)
       : TCryptoLibGenericArray<TBigInteger>; virtual;
       : TCryptoLibGenericArray<TBigInteger>; virtual;
 
 
@@ -61,31 +59,6 @@ implementation
 
 
 { TGlvTypeBEndomorphism }
 { 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;
 constructor TGlvTypeBEndomorphism.Create(const curve: IECCurve;
   const parameters: IGlvTypeBParameters);
   const parameters: IGlvTypeBParameters);
 begin
 begin
@@ -101,25 +74,8 @@ end;
 
 
 function TGlvTypeBEndomorphism.DecomposeScalar(const k: TBigInteger)
 function TGlvTypeBEndomorphism.DecomposeScalar(const k: TBigInteger)
   : TCryptoLibGenericArray<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
 begin
-  inherited Destroy;
+  Result := TEndoUtilities.DecomposeScalar(FParameters.SplitParams, k);
 end;
 end;
 
 
 function TGlvTypeBEndomorphism.GetHasEfficientPointMap: Boolean;
 function TGlvTypeBEndomorphism.GetHasEfficientPointMap: Boolean;

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

@@ -24,48 +24,29 @@ interface
 uses
 uses
   ClpBigInteger,
   ClpBigInteger,
   ClpIGlvTypeBParameters,
   ClpIGlvTypeBParameters,
+  ClpIScalarSplitParameters,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
-resourcestring
-  SInvalidParameters = '"%s" must consist of exactly 2 (initialized) values';
-
 type
 type
   TGlvTypeBParameters = class sealed(TInterfacedObject, IGlvTypeBParameters)
   TGlvTypeBParameters = class sealed(TInterfacedObject, IGlvTypeBParameters)
 
 
   strict private
   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 GetLambda: TBigInteger; inline;
     function GetBeta: 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
   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 lambda: TBigInteger read GetLambda;
     property beta: TBigInteger read GetBeta;
     property beta: TBigInteger read GetBeta;
-    property bits: Int32 read GetBits;
+    property splitParams: IScalarSplitParameters read GetSplitParams;
 
 
   end;
   end;
 
 
@@ -73,67 +54,13 @@ implementation
 
 
 { TGlvTypeBParameters }
 { 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;
 constructor TGlvTypeBParameters.Create(const beta, lambda: TBigInteger;
-  const v1, v2: TCryptoLibGenericArray<TBigInteger>; const g1, g2: TBigInteger;
-  bits: Int32);
+  const splitParams: IScalarSplitParameters);
 begin
 begin
-  CheckVector(v1, 'v1');
-  CheckVector(v2, 'v2');
-
+  Inherited Create();
   Fbeta := beta;
   Fbeta := beta;
   Flambda := lambda;
   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;
 end;
 
 
 function TGlvTypeBParameters.GetBeta: TBigInteger;
 function TGlvTypeBParameters.GetBeta: TBigInteger;
@@ -141,14 +68,14 @@ begin
   Result := Fbeta;
   Result := Fbeta;
 end;
 end;
 
 
-function TGlvTypeBParameters.GetBits: Int32;
+function TGlvTypeBParameters.GetLambda: TBigInteger;
 begin
 begin
-  Result := Fbits;
+  Result := Flambda;
 end;
 end;
 
 
-function TGlvTypeBParameters.GetLambda: TBigInteger;
+function TGlvTypeBParameters.GetSplitParams: IScalarSplitParameters;
 begin
 begin
-  Result := Flambda;
+  Result := FsplitParams;
 end;
 end;
 
 
 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}
 {$I ..\..\..\Include\CryptoLib.inc}
 
 
@@ -23,11 +23,11 @@ interface
 
 
 uses
 uses
   ClpIPreCompInfo,
   ClpIPreCompInfo,
-  ClpIValidityPrecompInfo;
+  ClpIValidityPreCompInfo;
 
 
 type
 type
-  TValidityPrecompInfo = class(TInterfacedObject, IPreCompInfo,
-    IValidityPrecompInfo)
+  TValidityPreCompInfo = class(TInterfacedObject, IPreCompInfo,
+    IValidityPreCompInfo)
 
 
   strict private
   strict private
 
 
@@ -52,9 +52,9 @@ type
 
 
 implementation
 implementation
 
 
-{ TValidityPrecompInfo }
+{ TValidityPreCompInfo }
 
 
-constructor TValidityPrecompInfo.Create;
+constructor TValidityPreCompInfo.Create;
 begin
 begin
   Inherited Create();
   Inherited Create();
   Ffailed := False;
   Ffailed := False;
@@ -62,32 +62,32 @@ begin
   ForderPassed := False;
   ForderPassed := False;
 end;
 end;
 
 
-function TValidityPrecompInfo.HasCurveEquationPassed: Boolean;
+function TValidityPreCompInfo.HasCurveEquationPassed: Boolean;
 begin
 begin
   result := FcurveEquationPassed;
   result := FcurveEquationPassed;
 end;
 end;
 
 
-function TValidityPrecompInfo.HasFailed: Boolean;
+function TValidityPreCompInfo.HasFailed: Boolean;
 begin
 begin
   result := Ffailed;
   result := Ffailed;
 end;
 end;
 
 
-function TValidityPrecompInfo.HasOrderPassed: Boolean;
+function TValidityPreCompInfo.HasOrderPassed: Boolean;
 begin
 begin
   result := ForderPassed;
   result := ForderPassed;
 end;
 end;
 
 
-procedure TValidityPrecompInfo.ReportCurveEquationPassed;
+procedure TValidityPreCompInfo.ReportCurveEquationPassed;
 begin
 begin
   FcurveEquationPassed := True;
   FcurveEquationPassed := True;
 end;
 end;
 
 
-procedure TValidityPrecompInfo.ReportFailed;
+procedure TValidityPreCompInfo.ReportFailed;
 begin
 begin
   Ffailed := True;
   Ffailed := True;
 end;
 end;
 
 
-procedure TValidityPrecompInfo.ReportOrderPassed;
+procedure TValidityPreCompInfo.ReportOrderPassed;
 begin
 begin
   ForderPassed := True;
   ForderPassed := True;
 end;
 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
   /// Class holding precomputation data for the WNAF (Window Non-Adjacent
   /// Form) algorithm.
   /// Form) algorithm.
   /// </summary>
   /// </summary>
-  TWNafPreCompInfo = class(TInterfacedObject, IPreCompInfo, IWNafPreCompInfo)
+  TWNafPreCompInfo = class sealed(TInterfacedObject, IPreCompInfo,
+    IWNafPreCompInfo)
 
 
   strict private
   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
   var
     /// <summary>
     /// <summary>
     /// Array holding the precomputed <c>ECPoint</c>s used for a Window NAF
     /// Array holding the precomputed <c>ECPoint</c>s used for a Window NAF
     /// multiplication.
     /// multiplication.
     /// </summary>
     /// </summary>
-    Fm_preComp: TCryptoLibGenericArray<IECPoint>;
+    FPreComp: TCryptoLibGenericArray<IECPoint>;
 
 
     /// <summary>
     /// <summary>
     /// Array holding the negations of the precomputed <c>ECPoint</c>s used
     /// Array holding the negations of the precomputed <c>ECPoint</c>s used
     /// for a Window NAF multiplication.
     /// for a Window NAF multiplication.
     /// </summary>
     /// </summary>
-    Fm_preCompNeg: TCryptoLibGenericArray<IECPoint>;
+    FPreCompNeg: TCryptoLibGenericArray<IECPoint>;
 
 
     /// <summary>
     /// <summary>
     /// Holds an <c>ECPoint</c> representing Twice(this). Used for the Window
     /// Holds an <c>ECPoint</c> representing Twice(this). Used for the Window
     /// NAF multiplication to create or extend the precomputed values.
     /// NAF multiplication to create or extend the precomputed values.
     /// </summary>
     /// </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
   public
 
 
     constructor Create();
     constructor Create();
-    destructor Destroy; override;
     property PreComp: TCryptoLibGenericArray<IECPoint> read GetPreComp
     property PreComp: TCryptoLibGenericArray<IECPoint> read GetPreComp
       write SetPreComp;
       write SetPreComp;
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
       write SetPreCompNeg;
       write SetPreCompNeg;
     property Twice: IECPoint read GetTwice write SetTwice;
     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;
   end;
 
 
 implementation
 implementation
@@ -83,43 +108,97 @@ implementation
 constructor TWNafPreCompInfo.Create;
 constructor TWNafPreCompInfo.Create;
 begin
 begin
   inherited Create();
   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;
 end;
 
 
-destructor TWNafPreCompInfo.Destroy;
+function TWNafPreCompInfo.GetConfWidth: Int32;
 begin
 begin
-  inherited Destroy;
+  result := FConfWidth;
 end;
 end;
 
 
 function TWNafPreCompInfo.GetPreComp: TCryptoLibGenericArray<IECPoint>;
 function TWNafPreCompInfo.GetPreComp: TCryptoLibGenericArray<IECPoint>;
 begin
 begin
-  Result := Fm_preComp;
+  result := FPreComp;
 end;
 end;
 
 
 function TWNafPreCompInfo.GetPreCompNeg: TCryptoLibGenericArray<IECPoint>;
 function TWNafPreCompInfo.GetPreCompNeg: TCryptoLibGenericArray<IECPoint>;
 begin
 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;
 end;
 
 
 function TWNafPreCompInfo.GetTwice: IECPoint;
 function TWNafPreCompInfo.GetTwice: IECPoint;
 begin
 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;
 end;
 
 
 procedure TWNafPreCompInfo.SetPreComp(const Value
 procedure TWNafPreCompInfo.SetPreComp(const Value
   : TCryptoLibGenericArray<IECPoint>);
   : TCryptoLibGenericArray<IECPoint>);
 begin
 begin
-  Fm_preComp := Value;
+  FPreComp := Value;
 end;
 end;
 
 
 procedure TWNafPreCompInfo.SetPreCompNeg(const Value
 procedure TWNafPreCompInfo.SetPreCompNeg(const Value
   : TCryptoLibGenericArray<IECPoint>);
   : TCryptoLibGenericArray<IECPoint>);
 begin
 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;
 end;
 
 
 procedure TWNafPreCompInfo.SetTwice(const Value: IECPoint);
 procedure TWNafPreCompInfo.SetTwice(const Value: IECPoint);
 begin
 begin
-  Fm_twice := Value;
+  FTwice := Value;
+end;
+
+procedure TWNafPreCompInfo.SetWidth(Value: Int32);
+begin
+  FWidth := Value;
 end;
 end;
 
 
 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;
     class procedure PruneScalar(const n: TCryptoLibByteArray; nOff: Int32;
       const r: TCryptoLibByteArray); static; inline;
       const r: TCryptoLibByteArray); static; inline;
 
 
-    class procedure ScalarMult(const k: TCryptoLibByteArray;
-      var p: TPointAffine; var r: TPointAccum); static;
-
     class function ReduceScalar(const n: TCryptoLibByteArray)
     class function ReduceScalar(const n: TCryptoLibByteArray)
       : TCryptoLibByteArray; static;
       : TCryptoLibByteArray; static;
 
 
@@ -303,7 +300,7 @@ type
     class procedure ScalarMultBaseEncoded(const k, r: TCryptoLibByteArray;
     class procedure ScalarMultBaseEncoded(const k, r: TCryptoLibByteArray;
       rOff: Int32); static; inline;
       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;
       var p: TPointAffine; var r: TPointAccum); static;
 
 
     class function ValidateDigestOutputSize(const ADigest: IDigest)
     class function ValidateDigestOutputSize(const ADigest: IDigest)
@@ -345,6 +342,7 @@ type
 
 
   class procedure Precompute(); static;
   class procedure Precompute(); static;
 
 
+  // NOTE: Only for use by X25519
   class procedure ScalarMultBaseYZ(const k: TCryptoLibByteArray; kOff: Int32;
   class procedure ScalarMultBaseYZ(const k: TCryptoLibByteArray; kOff: Int32;
     const Y, Z: TCryptoLibInt32Array); static; inline;
     const Y, Z: TCryptoLibInt32Array); static; inline;
 
 
@@ -398,6 +396,9 @@ type
     const pk: TCryptoLibByteArray; pkOff: Int32; const ctx: TCryptoLibByteArray;
     const pk: TCryptoLibByteArray; pkOff: Int32; const ctx: TCryptoLibByteArray;
     const ph: IDigest): Boolean; overload;
     const ph: IDigest): Boolean; overload;
 
 
+  class procedure ScalarMult(const k: TCryptoLibByteArray; var p: TPointAffine;
+    var r: TPointAccum); static;
+
   end;
   end;
 
 
 implementation
 implementation
@@ -765,18 +766,28 @@ begin
   TX25519Field.Copy(table, off, r.T, 0);
   TX25519Field.Copy(table, off, r.T, 0);
 end;
 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;
 class procedure TEd25519.PointLookup(const X: TCryptoLibUInt32Array; n: Int32;
   const table: TCryptoLibInt32Array; var r: TPointExt);
   const table: TCryptoLibInt32Array; var r: TPointExt);
 var
 var
-  w, Sign, abs, i, off, cond: Int32;
+  w, LSign, abs, i, off, cond: Int32;
 begin
 begin
   w := GetWindow4(X, n);
   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}
 {$IFDEF DEBUG}
-  System.Assert((Sign = 0) or (Sign = 1));
+  System.Assert((LSign = 0) or (LSign = 1));
   System.Assert((abs <= 0) and (abs < PrecompPoints));
   System.Assert((abs <= 0) and (abs < PrecompPoints));
 {$ENDIF DEBUG}
 {$ENDIF DEBUG}
   i := 0;
   i := 0;
@@ -796,8 +807,8 @@ begin
     System.Inc(i);
     System.Inc(i);
   end;
   end;
 
 
-  TX25519Field.CNegate(Sign, r.X);
-  TX25519Field.CNegate(Sign, r.T);
+  TX25519Field.CNegate(LSign, r.X);
+  TX25519Field.CNegate(LSign, r.T);
 end;
 end;
 
 
 class function TEd25519.DecodePointVar(const p: TCryptoLibByteArray;
 class function TEd25519.DecodePointVar(const p: TCryptoLibByteArray;
@@ -932,17 +943,6 @@ begin
   ScalarMultBaseEncoded(s, pk, pkOff);
   ScalarMultBaseEncoded(s, pk, pkOff);
 end;
 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)
 class function TEd25519.GetWnaf(const n: TCryptoLibUInt32Array; width: Int32)
   : TCryptoLibShortIntArray;
   : TCryptoLibShortIntArray;
 var
 var
@@ -1156,7 +1156,7 @@ begin
   DecodeScalar(k, 0, nA);
   DecodeScalar(k, 0, nA);
 
 
   pR := TPointAccum.CreatePointAccum();
   pR := TPointAccum.CreatePointAccum();
-  ScalarMultStraussVar(nS, nA, pA, pR);
+  ScalarMultStrausVar(nS, nA, pA, pR);
 
 
   System.SetLength(check, PointBytes);
   System.SetLength(check, PointBytes);
 
 
@@ -1935,7 +1935,7 @@ begin
   TX25519Field.Copy(p.Z, 0, Z, 0);
   TX25519Field.Copy(p.Z, 0, Z, 0);
 end;
 end;
 
 
-class procedure TEd25519.ScalarMultStraussVar(const nb,
+class procedure TEd25519.ScalarMultStrausVar(const nb,
   np: TCryptoLibUInt32Array; var p: TPointAffine; var r: TPointAccum);
   np: TCryptoLibUInt32Array; var p: TPointAffine; var r: TPointAccum);
 var
 var
   width, bit, wb, wp, LSign, index: Int32;
   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;
       xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32); overload;
       static; inline;
       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 Create(len: Int32): TCryptoLibUInt32Array; static; inline;
 
 
     class function Create64(len: Int32): TCryptoLibUInt64Array; static; inline;
     class function Create64(len: Int32): TCryptoLibUInt64Array; static; inline;
@@ -151,6 +161,9 @@ type
     class function FromBigInteger(bits: Int32; const x: TBigInteger)
     class function FromBigInteger(bits: Int32; const x: TBigInteger)
       : TCryptoLibUInt32Array; static;
       : TCryptoLibUInt32Array; static;
 
 
+    class function FromBigInteger64(bits: Int32; const x: TBigInteger)
+      : TCryptoLibUInt64Array; static;
+
     class function GetBit(const x: TCryptoLibUInt32Array; bit: Int32)
     class function GetBit(const x: TCryptoLibUInt32Array; bit: Int32)
       : UInt32; static;
       : UInt32; static;
 
 
@@ -961,7 +974,7 @@ end;
 class procedure TNat.CMov(len, mask: Int32; const x: TCryptoLibUInt32Array;
 class procedure TNat.CMov(len, mask: Int32; const x: TCryptoLibUInt32Array;
   xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32);
   xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32);
 var
 var
-  LMASK, z_i, Diff: UInt32;
+  LMASK, z_i, LDiff: UInt32;
   I: Int32;
   I: Int32;
 begin
 begin
   LMASK := UInt32(-(mask and 1));
   LMASK := UInt32(-(mask and 1));
@@ -969,8 +982,8 @@ begin
   for I := 0 to System.Pred(len) do
   for I := 0 to System.Pred(len) do
   begin
   begin
     z_i := z[zOff + I];
     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;
     z[zOff + I] := z_i;
   end;
   end;
 end;
 end;
@@ -987,6 +1000,24 @@ begin
   System.Move(x[0], z[0], len * System.SizeOf(UInt32));
   System.Move(x[0], z[0], len * System.SizeOf(UInt32));
 end;
 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;
 class procedure TNat.Copy(len: Int32; const x: TCryptoLibUInt32Array;
   xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32);
   xOff: Int32; const z: TCryptoLibUInt32Array; zOff: Int32);
 begin
 begin
@@ -1180,6 +1211,31 @@ begin
   end;
   end;
 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;
 class function TNat.GetBit(const x: TCryptoLibUInt32Array; bit: Int32): UInt32;
 var
 var
   w, b: Int32;
   w, b: Int32;

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

@@ -232,7 +232,7 @@ contains
   ClpIHMacDsaKCalculator in '..\..\Interfaces\ClpIHMacDsaKCalculator.pas',
   ClpIHMacDsaKCalculator in '..\..\Interfaces\ClpIHMacDsaKCalculator.pas',
   ClpInterleave in '..\..\Math\Raw\ClpInterleave.pas',
   ClpInterleave in '..\..\Math\Raw\ClpInterleave.pas',
   ClpIPreCompCallBack in '..\..\Interfaces\ClpIPreCompCallBack.pas',
   ClpIPreCompCallBack in '..\..\Interfaces\ClpIPreCompCallBack.pas',
-  ClpIValidityPrecompInfo in '..\..\Interfaces\ClpIValidityPrecompInfo.pas',
+  ClpIValidityPreCompInfo in '..\..\Interfaces\ClpIValidityPreCompInfo.pas',
   ClpNat192 in '..\..\Math\Raw\ClpNat192.pas',
   ClpNat192 in '..\..\Math\Raw\ClpNat192.pas',
   ClpNat256 in '..\..\Math\Raw\ClpNat256.pas',
   ClpNat256 in '..\..\Math\Raw\ClpNat256.pas',
   ClpNat320 in '..\..\Math\Raw\ClpNat320.pas',
   ClpNat320 in '..\..\Math\Raw\ClpNat320.pas',
@@ -283,7 +283,6 @@ contains
   ClpECDHBasicAgreement in '..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas',
   ClpECDHBasicAgreement in '..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas',
   ClpGenericPolynomialExtensionField in '..\..\Math\Field\ClpGenericPolynomialExtensionField.pas',
   ClpGenericPolynomialExtensionField in '..\..\Math\Field\ClpGenericPolynomialExtensionField.pas',
   ClpGF2Polynomial in '..\..\Math\Field\ClpGF2Polynomial.pas',
   ClpGF2Polynomial in '..\..\Math\Field\ClpGF2Polynomial.pas',
-  ClpGlvMultiplier in '..\..\Math\EC\Multiplier\ClpGlvMultiplier.pas',
   ClpIAesEngine in '..\..\Interfaces\ClpIAesEngine.pas',
   ClpIAesEngine in '..\..\Interfaces\ClpIAesEngine.pas',
   ClpIBlockCipher in '..\..\Interfaces\ClpIBlockCipher.pas',
   ClpIBlockCipher in '..\..\Interfaces\ClpIBlockCipher.pas',
   ClpIBlockCipherPadding in '..\..\Interfaces\ClpIBlockCipherPadding.pas',
   ClpIBlockCipherPadding in '..\..\Interfaces\ClpIBlockCipherPadding.pas',
@@ -293,13 +292,10 @@ contains
   ClpIDsaDigestSigner in '..\..\Interfaces\ClpIDsaDigestSigner.pas',
   ClpIDsaDigestSigner in '..\..\Interfaces\ClpIDsaDigestSigner.pas',
   ClpIGenericPolynomialExtensionField in '..\..\Interfaces\ClpIGenericPolynomialExtensionField.pas',
   ClpIGenericPolynomialExtensionField in '..\..\Interfaces\ClpIGenericPolynomialExtensionField.pas',
   ClpIGF2Polynomial in '..\..\Interfaces\ClpIGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\Interfaces\ClpIGF2Polynomial.pas',
-  ClpIGlvMultiplier in '..\..\Interfaces\ClpIGlvMultiplier.pas',
   ClpIKeyParameter in '..\..\Interfaces\ClpIKeyParameter.pas',
   ClpIKeyParameter in '..\..\Interfaces\ClpIKeyParameter.pas',
   ClpIPaddedBufferedBlockCipher in '..\..\Interfaces\ClpIPaddedBufferedBlockCipher.pas',
   ClpIPaddedBufferedBlockCipher in '..\..\Interfaces\ClpIPaddedBufferedBlockCipher.pas',
   ClpIParametersWithIV in '..\..\Interfaces\ClpIParametersWithIV.pas',
   ClpIParametersWithIV in '..\..\Interfaces\ClpIParametersWithIV.pas',
   ClpIPrimeField in '..\..\Interfaces\ClpIPrimeField.pas',
   ClpIPrimeField in '..\..\Interfaces\ClpIPrimeField.pas',
-  ClpIWNafL2RMultiplier in '..\..\Interfaces\ClpIWNafL2RMultiplier.pas',
-  ClpIWTauNafMultiplier in '..\..\Interfaces\ClpIWTauNafMultiplier.pas',
   ClpIWTauNafPreCompInfo in '..\..\Interfaces\ClpIWTauNafPreCompInfo.pas',
   ClpIWTauNafPreCompInfo in '..\..\Interfaces\ClpIWTauNafPreCompInfo.pas',
   ClpIZTauElement in '..\..\Interfaces\ClpIZTauElement.pas',
   ClpIZTauElement in '..\..\Interfaces\ClpIZTauElement.pas',
   ClpKeyParameter in '..\..\Crypto\Parameters\ClpKeyParameter.pas',
   ClpKeyParameter in '..\..\Crypto\Parameters\ClpKeyParameter.pas',
@@ -307,23 +303,17 @@ contains
   ClpParametersWithIV in '..\..\Crypto\Parameters\ClpParametersWithIV.pas',
   ClpParametersWithIV in '..\..\Crypto\Parameters\ClpParametersWithIV.pas',
   ClpPrimeField in '..\..\Math\Field\ClpPrimeField.pas',
   ClpPrimeField in '..\..\Math\Field\ClpPrimeField.pas',
   ClpSetWeakRef in '..\..\Utils\ClpSetWeakRef.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',
   ClpWTauNafPreCompInfo in '..\..\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
   ClpZTauElement in '..\..\Math\EC\Abc\ClpZTauElement.pas',
   ClpZTauElement in '..\..\Math\EC\Abc\ClpZTauElement.pas',
-  ClpAbstractECMultiplier in '..\..\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
   ClpArrayUtils in '..\..\Utils\ClpArrayUtils.pas',
   ClpArrayUtils in '..\..\Utils\ClpArrayUtils.pas',
   ClpBigIntegers in '..\..\Utils\ClpBigIntegers.pas',
   ClpBigIntegers in '..\..\Utils\ClpBigIntegers.pas',
-  ClpFixedPointCombMultiplier in '..\..\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
   ClpFixedPointPreCompInfo in '..\..\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
   ClpFixedPointPreCompInfo in '..\..\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
-  ClpFixedPointUtilities in '..\..\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
   ClpGlvTypeBEndomorphism in '..\..\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBEndomorphism in '..\..\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
   ClpGlvTypeBParameters in '..\..\Math\EC\Endo\ClpGlvTypeBParameters.pas',
   ClpGlvTypeBParameters in '..\..\Math\EC\Endo\ClpGlvTypeBParameters.pas',
   ClpIDsa in '..\..\Interfaces\ClpIDsa.pas',
   ClpIDsa in '..\..\Interfaces\ClpIDsa.pas',
   ClpIDsaKCalculator in '..\..\Interfaces\ClpIDsaKCalculator.pas',
   ClpIDsaKCalculator in '..\..\Interfaces\ClpIDsaKCalculator.pas',
   ClpIECDsaSigner in '..\..\Interfaces\ClpIECDsaSigner.pas',
   ClpIECDsaSigner in '..\..\Interfaces\ClpIECDsaSigner.pas',
   ClpIFiniteField in '..\..\Interfaces\ClpIFiniteField.pas',
   ClpIFiniteField in '..\..\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier in '..\..\Interfaces\ClpIFixedPointCombMultiplier.pas',
   ClpIFixedPointPreCompInfo in '..\..\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIFixedPointPreCompInfo in '..\..\Interfaces\ClpIFixedPointPreCompInfo.pas',
   ClpIGlvEndomorphism in '..\..\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvEndomorphism in '..\..\Interfaces\ClpIGlvEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\Interfaces\ClpIGlvTypeBEndomorphism.pas',
   ClpIGlvTypeBEndomorphism in '..\..\Interfaces\ClpIGlvTypeBEndomorphism.pas',
@@ -349,7 +339,6 @@ contains
   ClpTimes in '..\..\Utils\ClpTimes.pas',
   ClpTimes in '..\..\Utils\ClpTimes.pas',
   ClpWNafPreCompInfo in '..\..\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpWNafPreCompInfo in '..\..\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpAsymmetricCipherKeyPair in '..\..\Crypto\ClpAsymmetricCipherKeyPair.pas',
   ClpAsymmetricCipherKeyPair in '..\..\Crypto\ClpAsymmetricCipherKeyPair.pas',
-  ClpIAbstractECMultiplier in '..\..\Interfaces\ClpIAbstractECMultiplier.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPair in '..\..\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricCipherKeyPairGenerator in '..\..\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
   ClpIAsymmetricKeyParameter in '..\..\Interfaces\ClpIAsymmetricKeyParameter.pas',
   ClpIAsymmetricKeyParameter in '..\..\Interfaces\ClpIAsymmetricKeyParameter.pas',
@@ -360,7 +349,7 @@ contains
   ClpIECKeyPairGenerator in '..\..\Interfaces\ClpIECKeyPairGenerator.pas',
   ClpIECKeyPairGenerator in '..\..\Interfaces\ClpIECKeyPairGenerator.pas',
   ClpIExtensionField in '..\..\Interfaces\ClpIExtensionField.pas',
   ClpIExtensionField in '..\..\Interfaces\ClpIExtensionField.pas',
   ClpOidTokenizer in '..\..\Asn1\ClpOidTokenizer.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',
   ClpTeleTrusTNamedCurves in '..\..\Asn1\TeleTrust\ClpTeleTrusTNamedCurves.pas',
   ClpAgreementUtilities in '..\..\Security\ClpAgreementUtilities.pas',
   ClpAgreementUtilities in '..\..\Security\ClpAgreementUtilities.pas',
   ClpIKdf1BytesGenerator in '..\..\Interfaces\ClpIKdf1BytesGenerator.pas',
   ClpIKdf1BytesGenerator in '..\..\Interfaces\ClpIKdf1BytesGenerator.pas',
@@ -402,6 +391,22 @@ contains
   ClpIDHValidationParameters in '..\..\Interfaces\ClpIDHValidationParameters.pas',
   ClpIDHValidationParameters in '..\..\Interfaces\ClpIDHValidationParameters.pas',
   ClpIDHDomainParameters in '..\..\Interfaces\ClpIDHDomainParameters.pas',
   ClpIDHDomainParameters in '..\..\Interfaces\ClpIDHDomainParameters.pas',
   ClpIDHValidationParams in '..\..\Interfaces\ClpIDHValidationParams.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.
 end.

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

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

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

@@ -18,40 +18,35 @@ uses
   ClpECKeyParameters, ClpECPrivateKeyParameters, ClpECPublicKeyParameters, 
   ClpECKeyParameters, ClpECPrivateKeyParameters, ClpECPublicKeyParameters, 
   ClpParametersWithRandom, ClpCryptoApiRandomGenerator, 
   ClpParametersWithRandom, ClpCryptoApiRandomGenerator, 
   ClpDigestRandomGenerator, ClpDsaDigestSigner, ClpECDsaSigner, 
   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, 
   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, 
   ClpPascalCoinECIESKdfBytesGenerator, ClpPascalCoinIESEngine, 
   ClpBaseKdfBytesGenerator, ClpIESEngine, ClpECIESPublicKeyParser, 
   ClpBaseKdfBytesGenerator, ClpIESEngine, ClpECIESPublicKeyParser, 
   ClpIESCipher, ClpECDHBasicAgreement, ClpEphemeralKeyPair, ClpKeyEncoder, 
   ClpIESCipher, ClpECDHBasicAgreement, ClpEphemeralKeyPair, ClpKeyEncoder, 
@@ -79,12 +74,12 @@ uses
   ClpIECDHCBasicAgreement, ClpHMacDsaKCalculator, ClpIHMacDsaKCalculator, 
   ClpIECDHCBasicAgreement, ClpHMacDsaKCalculator, ClpIHMacDsaKCalculator, 
   ClpHkdfBytesGenerator, ClpIHkdfBytesGenerator, ClpHkdfParameters, 
   ClpHkdfBytesGenerator, ClpIHkdfBytesGenerator, ClpHkdfParameters, 
   ClpIHkdfParameters, ClpDsaParameterGenerationParameters, 
   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, 
   ClpISchnorrDigestSigner, ClpIECSchnorrSipaSigner, ClpECSchnorrSipaSigner, 
   ClpSchnorrDigestSigner, ClpISchnorr, ClpISchnorrExt, ClpBlowfishEngine, 
   ClpSchnorrDigestSigner, ClpISchnorr, ClpISchnorrExt, ClpBlowfishEngine, 
   ClpIBlowfishEngine, ClpECC, ClpAsn1Objects, ClpSignersEncodings, 
   ClpIBlowfishEngine, ClpECC, ClpAsn1Objects, ClpSignersEncodings, 
@@ -133,7 +128,13 @@ uses
   ClpDHKeyGeneratorHelper, ClpDHParametersHelper, ClpDHPrivateKeyParameters, 
   ClpDHKeyGeneratorHelper, ClpDHParametersHelper, ClpDHPrivateKeyParameters, 
   ClpDHPublicKeyParameters, ClpDHKeyGenerationParameters, ClpDHKeyParameters, 
   ClpDHPublicKeyParameters, ClpDHKeyGenerationParameters, ClpDHKeyParameters, 
   ClpDHValidationParameters, ClpDHParameters, ClpDHDomainParameters, 
   ClpDHValidationParameters, ClpDHParameters, ClpDHDomainParameters, 
-  ClpDHValidationParams, ClpAESPRNGRandom;
+  ClpDHValidationParams, ClpAESPRNGRandom, ClpCryptLibObjectIdentifiers, 
+  ClpIEndoPreCompInfo, ClpEndoPreCompInfo, ClpScaleXNegateYPointMap, 
+  ClpScaleYNegateXPointMap, ClpGlvTypeAEndomorphism, ClpGlvTypeAParameters, 
+  ClpScalarSplitParameters, ClpIGlvTypeAParameters, ClpIGlvTypeAEndomorphism, 
+  ClpIScaleXNegateYPointMap, ClpIScaleYNegateXPointMap, 
+  ClpIScalarSplitParameters, ClpECCompUtilities, ClpValidityPreCompInfo, 
+  ClpIValidityPreCompInfo;
 
 
 implementation
 implementation
 
 

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

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