diff --git a/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr b/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr
index d696b5ef..e590967d 100644
--- a/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr
+++ b/CryptoLib.Benchmark/Delphi/CryptoLib.BenchmarkConsole.dpr
@@ -309,7 +309,25 @@ uses
ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyGenerationParameters.pas',
ClpKeyParameter in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyParameter.pas',
ClpKMac in '..\..\CryptoLib\src\Crypto\Macs\ClpKMac.pas',
- ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
+ ClpIBinPolyMul in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyMul.pas',
+ ClpIBinPolyInv in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyInv.pas',
+ ClpBinPolyMulBaseBinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseBinomialReduce.pas',
+ ClpBinPolyMulBaseTrinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseTrinomialReduce.pas',
+ ClpBinPolyMulBasePentanomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBasePentanomialReduce.pas',
+ ClpBinPolyScalarKernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarKernels.pas',
+ ClpBinPolyScalarMedium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarMedium.pas',
+ ClpBinPolyScalarLarge in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarLarge.pas',
+ ClpBinPolyScalarBackend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarBackend.pas',
+ ClpBinPolyX86V128Kernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Kernels.pas',
+ ClpBinPolyX86V128Sizes in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Sizes.pas',
+ ClpBinPolyX86V128Medium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Medium.pas',
+ ClpBinPolyX86V128Large in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Large.pas',
+ ClpBinPolyX86V128Backend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Backend.pas',
+ ClpBinPolyMulBase in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBase.pas',
+ ClpItohTsujiiInv in '..\..\CryptoLib\src\Math\BinPoly\ClpItohTsujiiInv.pas',
+ ClpBinPolys in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolys.pas',
+ ClpIF2mFieldData in '..\..\CryptoLib\src\Interfaces\Math\EC\ClpIF2mFieldData.pas',
+ ClpF2mFieldData in '..\..\CryptoLib\src\Math\EC\ClpF2mFieldData.pas',
ClpMacUtilities in '..\..\CryptoLib\src\Crypto\Macs\ClpMacUtilities.pas',
ClpMiscObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Misc\ClpMiscObjectIdentifiers.pas',
ClpMultipliers in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpMultipliers.pas',
diff --git a/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr b/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr
index 483feedd..06389068 100644
--- a/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr
+++ b/CryptoLib.Examples/Delphi.Examples/CryptoLib.Examples.dpr
@@ -314,7 +314,25 @@ uses
ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyGenerationParameters.pas',
ClpKeyParameter in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyParameter.pas',
ClpKMac in '..\..\CryptoLib\src\Crypto\Macs\ClpKMac.pas',
- ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
+ ClpIBinPolyMul in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyMul.pas',
+ ClpIBinPolyInv in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyInv.pas',
+ ClpBinPolyMulBaseBinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseBinomialReduce.pas',
+ ClpBinPolyMulBaseTrinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseTrinomialReduce.pas',
+ ClpBinPolyMulBasePentanomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBasePentanomialReduce.pas',
+ ClpBinPolyScalarKernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarKernels.pas',
+ ClpBinPolyScalarMedium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarMedium.pas',
+ ClpBinPolyScalarLarge in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarLarge.pas',
+ ClpBinPolyScalarBackend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarBackend.pas',
+ ClpBinPolyX86V128Kernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Kernels.pas',
+ ClpBinPolyX86V128Sizes in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Sizes.pas',
+ ClpBinPolyX86V128Medium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Medium.pas',
+ ClpBinPolyX86V128Large in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Large.pas',
+ ClpBinPolyX86V128Backend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Backend.pas',
+ ClpBinPolyMulBase in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBase.pas',
+ ClpItohTsujiiInv in '..\..\CryptoLib\src\Math\BinPoly\ClpItohTsujiiInv.pas',
+ ClpBinPolys in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolys.pas',
+ ClpIF2mFieldData in '..\..\CryptoLib\src\Interfaces\Math\EC\ClpIF2mFieldData.pas',
+ ClpF2mFieldData in '..\..\CryptoLib\src\Math\EC\ClpF2mFieldData.pas',
ClpMacUtilities in '..\..\CryptoLib\src\Crypto\Macs\ClpMacUtilities.pas',
ClpMiscObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Misc\ClpMiscObjectIdentifiers.pas',
ClpMultipliers in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpMultipliers.pas',
diff --git a/CryptoLib.Tests/Data/Pkcs/Pkcs12Store/Manifest.csv b/CryptoLib.Tests/Data/Pkcs/Pkcs12Store/Manifest.csv
index 4aacfe45..4ec252bd 100644
--- a/CryptoLib.Tests/Data/Pkcs/Pkcs12Store/Manifest.csv
+++ b/CryptoLib.Tests/Data/Pkcs/Pkcs12Store/Manifest.csv
@@ -13,3 +13,4 @@ SentrixSoft,Pkcs/Pkcs12Store/Stores/SentrixSoft.der,0000,Sentrix soft
Sentrix1,Pkcs/Pkcs12Store/Stores/Sentrix1.der,0000,Sentrix 1
Sentrix2,Pkcs/Pkcs12Store/Stores/Sentrix2.der,0000,Sentrix 2
Sentrix3,Pkcs/Pkcs12Store/Stores/Sentrix3.der,0000,Sentrix 3
+RawKeyBagStore,Pkcs/Pkcs12Store/Stores/RawKeyBagStore.der,,ONVIF raw keyBag store
diff --git a/CryptoLib.Tests/Data/Pkcs/Pkcs12Store/Stores/RawKeyBagStore.der b/CryptoLib.Tests/Data/Pkcs/Pkcs12Store/Stores/RawKeyBagStore.der
new file mode 100644
index 00000000..fe8a4ced
Binary files /dev/null and b/CryptoLib.Tests/Data/Pkcs/Pkcs12Store/Stores/RawKeyBagStore.der differ
diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
index 0a42f866..7b74a54d 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.Mobile.dpr
@@ -306,7 +306,25 @@ uses
ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyGenerationParameters.pas',
ClpKeyParameter in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyParameter.pas',
ClpKMac in '..\..\CryptoLib\src\Crypto\Macs\ClpKMac.pas',
- ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
+ ClpIBinPolyMul in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyMul.pas',
+ ClpIBinPolyInv in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyInv.pas',
+ ClpBinPolyMulBaseBinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseBinomialReduce.pas',
+ ClpBinPolyMulBaseTrinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseTrinomialReduce.pas',
+ ClpBinPolyMulBasePentanomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBasePentanomialReduce.pas',
+ ClpBinPolyScalarKernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarKernels.pas',
+ ClpBinPolyScalarMedium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarMedium.pas',
+ ClpBinPolyScalarLarge in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarLarge.pas',
+ ClpBinPolyScalarBackend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarBackend.pas',
+ ClpBinPolyX86V128Kernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Kernels.pas',
+ ClpBinPolyX86V128Sizes in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Sizes.pas',
+ ClpBinPolyX86V128Medium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Medium.pas',
+ ClpBinPolyX86V128Large in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Large.pas',
+ ClpBinPolyX86V128Backend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Backend.pas',
+ ClpBinPolyMulBase in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBase.pas',
+ ClpItohTsujiiInv in '..\..\CryptoLib\src\Math\BinPoly\ClpItohTsujiiInv.pas',
+ ClpBinPolys in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolys.pas',
+ ClpIF2mFieldData in '..\..\CryptoLib\src\Interfaces\Math\EC\ClpIF2mFieldData.pas',
+ ClpF2mFieldData in '..\..\CryptoLib\src\Math\EC\ClpF2mFieldData.pas',
ClpMacUtilities in '..\..\CryptoLib\src\Crypto\Macs\ClpMacUtilities.pas',
ClpMiscObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Misc\ClpMiscObjectIdentifiers.pas',
ClpMultipliers in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpMultipliers.pas',
@@ -716,7 +734,9 @@ uses
BlowfishTests in '..\src\Crypto\BlowfishTests.pas',
RijndaelTests in '..\src\Crypto\RijndaelTests.pas',
Asn1IntegerTests in '..\src\Asn1\Asn1IntegerTests.pas',
+ Asn1GeneratorTests in '..\src\Asn1\Asn1GeneratorTests.pas',
Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
+ Asn1TimeFormatTests in '..\src\Asn1\Asn1TimeFormatTests.pas',
BitStringTests in '..\src\Asn1\BitStringTests.pas',
DerUtf8StringTests in '..\src\Asn1\DerUtf8StringTests.pas',
EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas',
@@ -738,6 +758,7 @@ uses
PrimesTests in '..\src\Math\PrimesTests.pas',
//ECAlgorithmsTests in '..\src\Math\ECAlgorithmsTests.pas',
//ECPointTests in '..\src\Math\ECPointTests.pas',
+ BinPolyTests in '..\src\Math\BinPoly\BinPolyTests.pas',
SecP384R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP384R1FieldTests.pas',
DigestTests in '..\src\Others\DigestTests.pas',
ECDsa5Tests in '..\src\Others\ECDsa5Tests.pas',
@@ -813,6 +834,7 @@ uses
X931SignerTests in '..\src\Crypto\X931SignerTests.pas',
CertificateTests in '..\src\Asn1\X509\CertificateTests.pas',
AuthorityKeyIdentifierTests in '..\src\Asn1\X509\AuthorityKeyIdentifierTests.pas',
+ IdpRelativeNameTests in '..\src\Asn1\X509\IdpRelativeNameTests.pas',
GeneralNameTests in '..\src\Asn1\X509\GeneralNameTests.pas',
KeyUsageTests in '..\src\Asn1\X509\KeyUsageTests.pas',
SubjectKeyIdentifierTests in '..\src\Asn1\X509\SubjectKeyIdentifierTests.pas',
@@ -858,6 +880,8 @@ uses
Bip340SchnorrTests in '..\src\Crypto\Bip340SchnorrTests.pas',
Bip327MuSig2Tests in '..\src\Crypto\Bip327MuSig2Tests.pas',
SimdSelectSlotTests in '..\src\Misc\SimdSelectSlotTests.pas',
+ BinaryPrimitivesTests in '..\src\Misc\BinaryPrimitivesTests.pas',
+ ByteUtilitiesTests in '..\src\Utils\NumberUtilities\ByteUtilitiesTests.pas',
CryptoLibTestResourceLoader in '..\src\Utils\CryptoLibTestResourceLoader.pas',
CsvVectorParser in '..\src\Utils\Parsers\CsvVectorParser.pas',
JsonVectorParser in '..\src\Utils\Parsers\JsonVectorParser.pas',
diff --git a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
index 5f37105a..b6636478 100644
--- a/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
+++ b/CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
@@ -325,7 +325,25 @@ uses
ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyGenerationParameters.pas',
ClpKeyParameter in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyParameter.pas',
ClpKMac in '..\..\CryptoLib\src\Crypto\Macs\ClpKMac.pas',
- ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
+ ClpIBinPolyMul in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyMul.pas',
+ ClpIBinPolyInv in '..\..\CryptoLib\src\Interfaces\Math\BinPoly\ClpIBinPolyInv.pas',
+ ClpBinPolyMulBaseBinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseBinomialReduce.pas',
+ ClpBinPolyMulBaseTrinomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBaseTrinomialReduce.pas',
+ ClpBinPolyMulBasePentanomialReduce in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBasePentanomialReduce.pas',
+ ClpBinPolyScalarKernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarKernels.pas',
+ ClpBinPolyScalarMedium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarMedium.pas',
+ ClpBinPolyScalarLarge in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarLarge.pas',
+ ClpBinPolyScalarBackend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyScalarBackend.pas',
+ ClpBinPolyX86V128Kernels in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Kernels.pas',
+ ClpBinPolyX86V128Sizes in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Sizes.pas',
+ ClpBinPolyX86V128Medium in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Medium.pas',
+ ClpBinPolyX86V128Large in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Large.pas',
+ ClpBinPolyX86V128Backend in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyX86V128Backend.pas',
+ ClpBinPolyMulBase in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolyMulBase.pas',
+ ClpItohTsujiiInv in '..\..\CryptoLib\src\Math\BinPoly\ClpItohTsujiiInv.pas',
+ ClpBinPolys in '..\..\CryptoLib\src\Math\BinPoly\ClpBinPolys.pas',
+ ClpIF2mFieldData in '..\..\CryptoLib\src\Interfaces\Math\EC\ClpIF2mFieldData.pas',
+ ClpF2mFieldData in '..\..\CryptoLib\src\Math\EC\ClpF2mFieldData.pas',
ClpMacUtilities in '..\..\CryptoLib\src\Crypto\Macs\ClpMacUtilities.pas',
ClpMiscObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Misc\ClpMiscObjectIdentifiers.pas',
ClpMultipliers in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpMultipliers.pas',
@@ -735,7 +753,9 @@ uses
BlowfishTests in '..\src\Crypto\BlowfishTests.pas',
RijndaelTests in '..\src\Crypto\RijndaelTests.pas',
Asn1IntegerTests in '..\src\Asn1\Asn1IntegerTests.pas',
+ Asn1GeneratorTests in '..\src\Asn1\Asn1GeneratorTests.pas',
Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
+ Asn1TimeFormatTests in '..\src\Asn1\Asn1TimeFormatTests.pas',
BitStringTests in '..\src\Asn1\BitStringTests.pas',
DerUtf8StringTests in '..\src\Asn1\DerUtf8StringTests.pas',
EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas',
@@ -757,6 +777,7 @@ uses
PrimesTests in '..\src\Math\PrimesTests.pas',
ECAlgorithmsTests in '..\src\Math\ECAlgorithmsTests.pas',
ECPointTests in '..\src\Math\ECPointTests.pas',
+ BinPolyTests in '..\src\Math\BinPoly\BinPolyTests.pas',
SecP384R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP384R1FieldTests.pas',
DigestTests in '..\src\Others\DigestTests.pas',
ECDsa5Tests in '..\src\Others\ECDsa5Tests.pas',
@@ -832,6 +853,7 @@ uses
X931SignerTests in '..\src\Crypto\X931SignerTests.pas',
CertificateTests in '..\src\Asn1\X509\CertificateTests.pas',
AuthorityKeyIdentifierTests in '..\src\Asn1\X509\AuthorityKeyIdentifierTests.pas',
+ IdpRelativeNameTests in '..\src\Asn1\X509\IdpRelativeNameTests.pas',
GeneralNameTests in '..\src\Asn1\X509\GeneralNameTests.pas',
KeyUsageTests in '..\src\Asn1\X509\KeyUsageTests.pas',
SubjectKeyIdentifierTests in '..\src\Asn1\X509\SubjectKeyIdentifierTests.pas',
@@ -877,6 +899,8 @@ uses
Bip340SchnorrTests in '..\src\Crypto\Bip340SchnorrTests.pas',
Bip327MuSig2Tests in '..\src\Crypto\Bip327MuSig2Tests.pas',
SimdSelectSlotTests in '..\src\Misc\SimdSelectSlotTests.pas',
+ BinaryPrimitivesTests in '..\src\Misc\BinaryPrimitivesTests.pas',
+ ByteUtilitiesTests in '..\src\Utils\NumberUtilities\ByteUtilitiesTests.pas',
CryptoLibTestResourceLoader in '..\src\Utils\CryptoLibTestResourceLoader.pas',
CsvVectorParser in '..\src\Utils\Parsers\CsvVectorParser.pas',
JsonVectorParser in '..\src\Utils\Parsers\JsonVectorParser.pas',
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
index 7b63c76b..9847075c 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
@@ -23,7 +23,7 @@
-
+
@@ -79,7 +79,7 @@
-
+
@@ -737,6 +737,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -747,7 +771,7 @@
-
+
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
index 632e2307..1d23b0cc 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
@@ -3,23 +3,23 @@
{$mode objfpc}{$H+}
uses
- Interfaces, Forms, GuiTestRunner, Asn1SequenceParserTests,
- EqualsAndHashCodeTests, OIDTests, EnumeratedTests, ExternalTests,
- ParsingTests, ParseTests, StringTests, TagTests, BigIntegerTests,
- ECAlgorithmsTests, ECPointTests, SecP256R1FieldTests, SecP384R1FieldTests,
- ECDsa5Tests, ECTests, NamedCurveTests, SignerUtilitiesTests,
- SecureRandomTests, DigestRandomNumberTests, FixedPointTests, AESTests,
- AesLightTests, FusedExternalRegistrationTests, AesX86Tests, AESSICTests,
- SicBulkParityTests, EcbBulkParityTests, CbcBulkParityTests,
- SpeckBlockCipherTestBase, SpeckLegacyTests, SpeckTests, IESCipherTests,
- MD5HMacTests, SHA1HMacTests, SHA224HMacTests, SHA256HMacTests,
- SHA384HMacTests, SHA512HMacTests, RIPEMD128HMacTests, RIPEMD160HMacTests,
- HMacTests, Pkcs5Tests, HkdfGeneratorTests, ECIESTests, PascalCoinECIESTests,
- ECNRTests, PrimesTests, ECEncodingTests, PaddingTests, DSATests,
- DeterministicDsaTests, Salsa20Tests, XSalsa20Tests, ChaChaTests,
- ChaCha7539ProcessBlocks2Tests, HChaCha20Tests, XChaCha20Tests,
- XChaCha20Poly1305Tests, StreamCipherResetTests, CTSTests, X25519Tests,
- X448Tests, Ed25519Tests, Ed448Tests, X25519HigherLevelTests,
+ Interfaces, Forms, GuiTestRunner, Asn1GeneratorTests, Asn1SequenceParserTests,
+ Asn1TimeFormatTests, EqualsAndHashCodeTests, OIDTests, EnumeratedTests,
+ ExternalTests, ParsingTests, ParseTests, StringTests, TagTests,
+ BigIntegerTests, ECAlgorithmsTests, ECPointTests, BinPolyTests,
+ SecP256R1FieldTests, SecP384R1FieldTests, ECDsa5Tests, ECTests,
+ NamedCurveTests, SignerUtilitiesTests, SecureRandomTests,
+ DigestRandomNumberTests, FixedPointTests, AESTests, AesLightTests,
+ FusedExternalRegistrationTests, AesX86Tests, AESSICTests, SicBulkParityTests,
+ EcbBulkParityTests, CbcBulkParityTests, SpeckBlockCipherTestBase,
+ SpeckLegacyTests, SpeckTests, IESCipherTests, MD5HMacTests, SHA1HMacTests,
+ SHA224HMacTests, SHA256HMacTests, SHA384HMacTests, SHA512HMacTests,
+ RIPEMD128HMacTests, RIPEMD160HMacTests, HMacTests, Pkcs5Tests,
+ HkdfGeneratorTests, ECIESTests, PascalCoinECIESTests, ECNRTests, PrimesTests,
+ ECEncodingTests, PaddingTests, DSATests, DeterministicDsaTests, Salsa20Tests,
+ XSalsa20Tests, ChaChaTests, ChaCha7539ProcessBlocks2Tests, HChaCha20Tests,
+ XChaCha20Tests, XChaCha20Poly1305Tests, StreamCipherResetTests, CTSTests,
+ X25519Tests, X448Tests, Ed25519Tests, Ed448Tests, X25519HigherLevelTests,
Ed25519HigherLevelTests, ShortenedDigestTests, Kdf1GeneratorTests,
Kdf2GeneratorTests, DHKekGeneratorTests, ECDHKekGeneratorTests, Argon2Tests,
ScryptTests, DigestTests, CertTests, Curve25519KeyUtilitiesTests,
@@ -29,22 +29,24 @@
UtcTimeTests, InputStreamTests, SetTests, X9Tests, PrivateKeyInfoTests,
DerUtf8StringTests, EncryptedPrivateKeyInfoTests, Pkcs10CertRequestTests,
DeltaCertificateTests, CertificateTests, X509AltTests, X509ExtensionsTests,
- AuthorityKeyIdentifierTests, X509NameTests, SubjectKeyIdentifierTests,
- KeyUsageTests, GeneralNameTests, KMacTests, RSATests, PssTests, ISO9796Tests,
- RSABlindedTests, RSADigestSignerTests, X931SignerTests, CryptoIOStreamTests,
- CryptoIOSinkTests, OaepTests, RijndaelTests, BlowfishTests, Poly1305Tests,
- MacTests, ChaCha20Poly1305Tests, OcbTests, CcmTests, EaxTests, CMacTests,
- AeadTestUtilities, GcmReorderTests, GCMTests, GcmSivTests, GMacTests,
- Pkcs12Tests, Bip327MuSig2Tests, Bip340SchnorrTests, AlgorithmFinderTests,
- CryptoLibTestBase, SimdSelectSlotTests, PkcsEncryptedPrivateKeyInfoTests,
+ AuthorityKeyIdentifierTests, IdpRelativeNameTests, X509NameTests,
+ SubjectKeyIdentifierTests, KeyUsageTests, GeneralNameTests, KMacTests,
+ RSATests, PssTests, ISO9796Tests, RSABlindedTests, RSADigestSignerTests,
+ X931SignerTests, CryptoIOStreamTests, CryptoIOSinkTests, OaepTests,
+ RijndaelTests, BlowfishTests, Poly1305Tests, MacTests, ChaCha20Poly1305Tests,
+ OcbTests, CcmTests, EaxTests, CMacTests, AeadTestUtilities, GcmReorderTests,
+ GCMTests, GcmSivTests, GMacTests, Pkcs12Tests, Bip327MuSig2Tests,
+ Bip340SchnorrTests, AlgorithmFinderTests, CryptoLibTestBase,
+ SimdSelectSlotTests, BinaryPrimitivesTests, PkcsEncryptedPrivateKeyInfoTests,
Pkcs12StoreTests, OpenSslReaderTests, OpenSslWriterTests, X509CertGenTests,
X509CertificatePairTests, X509UtilitiesTests, FixedSecureRandom,
ShortenedDigest, CertTestUtilities, FusedKernelToggle,
CryptoLibTestResourceLoader, CryptoTestKeys, CsvVectorParser,
JsonVectorParser, Bip327Vectors, Bip340Vectors, HmacVectors, Argon2Vectors,
AsymmetricTestVectors, SymmetricBlockVectors, ChaChaPoly1305Vectors,
- OpenSslVectors, PemReaderVectors, PkcsVectors, CertVectors, TestKeyBuilders, PemDerCodec,
- Int32Tests, Int64Tests, IPAddressUtilitiesTests, PemReaderTests;
+ OpenSslVectors, PemReaderVectors, PkcsVectors, CertVectors, TestKeyBuilders,
+ PemDerCodec, Int32Tests, Int64Tests, ByteUtilitiesTests,
+ IPAddressUtilitiesTests, PemReaderTests;
{$R *.res}
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi
index 979d0034..3a44bd37 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpi
@@ -39,7 +39,7 @@
-
+
@@ -696,6 +696,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -706,7 +730,7 @@
-
+
diff --git a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
index c461af2c..26e52076 100644
--- a/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
+++ b/CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
@@ -4,23 +4,23 @@
uses
{$IFDEF UNIX}cwstring,{$ENDIF}
- consoletestrunner, Asn1SequenceParserTests, EqualsAndHashCodeTests, OIDTests,
- EnumeratedTests, ExternalTests, ParsingTests, ParseTests, StringTests,
- TagTests, BigIntegerTests, ECAlgorithmsTests, ECPointTests,
+ consoletestrunner, Asn1GeneratorTests, Asn1SequenceParserTests,
+ Asn1TimeFormatTests, EqualsAndHashCodeTests, OIDTests, EnumeratedTests,
+ ExternalTests, ParsingTests, ParseTests, StringTests, TagTests,
+ BigIntegerTests, ECAlgorithmsTests, ECPointTests, BinPolyTests,
SecP256R1FieldTests, SecP384R1FieldTests, ECDsa5Tests, ECTests,
NamedCurveTests, SignerUtilitiesTests, SecureRandomTests,
- DigestRandomNumberTests, FixedPointTests, AESTests,
- AesLightTests, FusedExternalRegistrationTests, AesX86Tests, AESSICTests,
- SicBulkParityTests, EcbBulkParityTests, CbcBulkParityTests,
- SpeckBlockCipherTestBase, SpeckLegacyTests, SpeckTests,
- IESCipherTests, MD5HMacTests, SHA1HMacTests, SHA224HMacTests, SHA256HMacTests,
- SHA384HMacTests, SHA512HMacTests, RIPEMD128HMacTests, RIPEMD160HMacTests,
- HMacTests, Pkcs5Tests, HkdfGeneratorTests, ECIESTests, PascalCoinECIESTests,
- ECNRTests, PrimesTests, ECEncodingTests, PaddingTests, DSATests,
- DeterministicDsaTests, Salsa20Tests, XSalsa20Tests, ChaChaTests,
- ChaCha7539ProcessBlocks2Tests, HChaCha20Tests, XChaCha20Tests,
- XChaCha20Poly1305Tests, StreamCipherResetTests, CTSTests, X25519Tests,
- X448Tests, Ed25519Tests, Ed448Tests, X25519HigherLevelTests,
+ DigestRandomNumberTests, FixedPointTests, AESTests, AesLightTests,
+ FusedExternalRegistrationTests, AesX86Tests, AESSICTests, SicBulkParityTests,
+ EcbBulkParityTests, CbcBulkParityTests, SpeckBlockCipherTestBase,
+ SpeckLegacyTests, SpeckTests, IESCipherTests, MD5HMacTests, SHA1HMacTests,
+ SHA224HMacTests, SHA256HMacTests, SHA384HMacTests, SHA512HMacTests,
+ RIPEMD128HMacTests, RIPEMD160HMacTests, HMacTests, Pkcs5Tests,
+ HkdfGeneratorTests, ECIESTests, PascalCoinECIESTests, ECNRTests, PrimesTests,
+ ECEncodingTests, PaddingTests, DSATests, DeterministicDsaTests, Salsa20Tests,
+ XSalsa20Tests, ChaChaTests, ChaCha7539ProcessBlocks2Tests, HChaCha20Tests,
+ XChaCha20Tests, XChaCha20Poly1305Tests, StreamCipherResetTests, CTSTests,
+ X25519Tests, X448Tests, Ed25519Tests, Ed448Tests, X25519HigherLevelTests,
Ed25519HigherLevelTests, Curve25519KeyUtilitiesTests, ShortenedDigestTests,
Kdf1GeneratorTests, Kdf2GeneratorTests, DHKekGeneratorTests,
ECDHKekGeneratorTests, Argon2Tests, ScryptTests, DigestTests, CertTests,
@@ -30,25 +30,24 @@
RelativeOidTests, OctetStringTests, SetTests, X9Tests, PrivateKeyInfoTests,
DerUtf8StringTests, EncryptedPrivateKeyInfoTests, Pkcs10CertRequestTests,
DeltaCertificateTests, CertificateTests, X509AltTests, X509ExtensionsTests,
- AuthorityKeyIdentifierTests, X509NameTests, SubjectKeyIdentifierTests,
- KeyUsageTests, GeneralNameTests, KMacTests, PssTests, ISO9796Tests,
- RSABlindedTests, RSADigestSignerTests, RSATests, X931SignerTests,
- CryptoIOStreamTests, CryptoIOSinkTests, OaepTests, RijndaelTests,
- BlowfishTests, CcmTests, ChaCha20Poly1305Tests, CMacTests, EaxTests, OcbTests,
- MacTests, Poly1305Tests, AeadTestUtilities, GcmReorderTests, GCMTests,
- GcmSivTests, GMacTests, Pkcs12Tests, Bip327MuSig2Tests, Bip340SchnorrTests,
- AlgorithmFinderTests, CryptoLibTestBase, SimdSelectSlotTests,
+ AuthorityKeyIdentifierTests, IdpRelativeNameTests, X509NameTests,
+ SubjectKeyIdentifierTests, KeyUsageTests, GeneralNameTests, KMacTests,
+ PssTests, ISO9796Tests, RSABlindedTests, RSADigestSignerTests, RSATests,
+ X931SignerTests, CryptoIOStreamTests, CryptoIOSinkTests, OaepTests,
+ RijndaelTests, BlowfishTests, CcmTests, ChaCha20Poly1305Tests, CMacTests,
+ EaxTests, OcbTests, MacTests, Poly1305Tests, AeadTestUtilities,
+ GcmReorderTests, GCMTests, GcmSivTests, GMacTests, Pkcs12Tests,
+ Bip327MuSig2Tests, Bip340SchnorrTests, AlgorithmFinderTests,
+ CryptoLibTestBase, SimdSelectSlotTests, BinaryPrimitivesTests,
PkcsEncryptedPrivateKeyInfoTests, Pkcs12StoreTests, OpenSslReaderTests,
OpenSslWriterTests, X509CertGenTests, X509CertificatePairTests,
- X509UtilitiesTests, FixedSecureRandom, ShortenedDigest,
- CertTestUtilities, CryptoTestKeys, FusedKernelToggle,
- CryptoLibTestResourceLoader, CsvVectorParser, JsonVectorParser,
- Bip327Vectors, Bip340Vectors, HmacVectors,
+ X509UtilitiesTests, FixedSecureRandom, ShortenedDigest, CertTestUtilities,
+ CryptoTestKeys, FusedKernelToggle, CryptoLibTestResourceLoader,
+ CsvVectorParser, JsonVectorParser, Bip327Vectors, Bip340Vectors, HmacVectors,
AsymmetricTestVectors, SymmetricBlockVectors, ChaChaPoly1305Vectors,
- OpenSslVectors, PkcsVectors, CertVectors,
- CsvVectorLoaderBase, TestKeyBuilders, PemDerCodec, PemReaderVectors, Argon2Vectors,
- Int32Tests, Int64Tests,
- IPAddressUtilitiesTests, PemReaderTests;
+ OpenSslVectors, PkcsVectors, CertVectors, CsvVectorLoaderBase,
+ TestKeyBuilders, PemDerCodec, PemReaderVectors, Argon2Vectors, Int32Tests,
+ Int64Tests, ByteUtilitiesTests, IPAddressUtilitiesTests, PemReaderTests;
type
diff --git a/CryptoLib.Tests/src/Asn1/Asn1GeneratorTests.pas b/CryptoLib.Tests/src/Asn1/Asn1GeneratorTests.pas
new file mode 100644
index 00000000..9478468e
--- /dev/null
+++ b/CryptoLib.Tests/src/Asn1/Asn1GeneratorTests.pas
@@ -0,0 +1,299 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit Asn1GeneratorTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+ Classes,
+ SysUtils,
+{$IFDEF FPC}
+ fpcunit,
+ testregistry,
+{$ELSE}
+ TestFramework,
+{$ENDIF FPC}
+ ClpAsn1Objects,
+ ClpIAsn1Objects,
+ ClpIAsn1Generators,
+ ClpAsn1Generators,
+ ClpIAsn1Core,
+ ClpAsn1Core,
+ ClpStreamUtilities,
+ ClpCryptoLibTypes,
+ ClpArrayUtilities,
+ CryptoLibTestBase;
+
+type
+
+ ///
+ /// ASN.1 streaming generator tests.
+ ///
+ TAsn1GeneratorTest = class(TCryptoLibAlgorithmTestCase)
+ private
+ procedure AddSequenceContents(const AGen: IBerSequenceGenerator); overload;
+ procedure AddSequenceContents(const AGen: IDerSequenceGenerator); overload;
+ procedure WriteOctets(const AGen: IBerOctetStringGenerator; const AOctets: TCryptoLibByteArray);
+ procedure TestTaggedBerSequence(ATagNo: Int32; ADeclaredExplicit: Boolean; const ASeq: IAsn1Sequence);
+ procedure TestTaggedDerSequence(ATagNo: Int32; ADeclaredExplicit: Boolean; const ASeq: IAsn1Sequence);
+ procedure TestTaggedBerOctetString(ATagNo: Int32; ADeclaredExplicit: Boolean; const AOctets: TCryptoLibByteArray);
+ procedure CheckSequenceRoundTrip(const AEncoding: TCryptoLibByteArray; ATagNo: Int32;
+ ADeclaredExplicit: Boolean; const AExpected: IAsn1Sequence);
+ procedure CheckBerOctetStringEncoding(const AEncoding, AExpectedOctets: TCryptoLibByteArray;
+ const AMessage: String);
+ procedure CheckTaggedOctetStringEncoding(const AEncoding: TCryptoLibByteArray; AExpectedTagNo: Int32;
+ ADeclaredExplicit: Boolean; const AExpectedOctets: TCryptoLibByteArray; const AMessage: String);
+ published
+ procedure TestAll;
+ end;
+
+implementation
+
+const
+ TAG_NOS: array[0..6] of Int32 = (0, 1, 30, 31, 127, 128, 5000);
+
+{ TAsn1GeneratorTest }
+
+procedure TAsn1GeneratorTest.AddSequenceContents(const AGen: IBerSequenceGenerator);
+begin
+ AGen.AddObject(TDerInteger.ValueOf(4095));
+ AGen.AddObject(TDerOctetString.FromContents(TCryptoLibByteArray.Create(1, 2, 3, 4)));
+end;
+
+procedure TAsn1GeneratorTest.AddSequenceContents(const AGen: IDerSequenceGenerator);
+begin
+ AGen.AddObject(TDerInteger.ValueOf(4095));
+ AGen.AddObject(TDerOctetString.FromContents(TCryptoLibByteArray.Create(1, 2, 3, 4)));
+end;
+
+procedure TAsn1GeneratorTest.WriteOctets(const AGen: IBerOctetStringGenerator; const AOctets: TCryptoLibByteArray);
+var
+ LOctOut: TStream;
+begin
+ LOctOut := AGen.GetOctetOutputStream();
+ try
+ if System.Length(AOctets) > 0 then
+ LOctOut.Write(AOctets[0], System.Length(AOctets));
+ finally
+ LOctOut.Free;
+ end;
+end;
+
+procedure TAsn1GeneratorTest.CheckSequenceRoundTrip(const AEncoding: TCryptoLibByteArray; ATagNo: Int32;
+ ADeclaredExplicit: Boolean; const AExpected: IAsn1Sequence);
+var
+ LTaggedObject: IAsn1TaggedObject;
+ LSequence: IAsn1Sequence;
+begin
+ LTaggedObject := TAsn1TaggedObject.GetInstance(AEncoding);
+ CheckTrue(LTaggedObject.HasContextTag(ATagNo),
+ 'seq tagNo [' + IntToStr(ATagNo) + ']');
+
+ LSequence := TAsn1Sequence.GetInstance(LTaggedObject, ADeclaredExplicit);
+ CheckTrue(AreEqual(AExpected.GetEncoded(TAsn1Encodable.Der),
+ LSequence.GetEncoded(TAsn1Encodable.Der)),
+ 'seq content [' + IntToStr(ATagNo) + '] explicit=' + SysUtils.BoolToStr(ADeclaredExplicit, True));
+end;
+
+procedure TAsn1GeneratorTest.CheckBerOctetStringEncoding(const AEncoding, AExpectedOctets: TCryptoLibByteArray;
+ const AMessage: String);
+var
+ LOctetString: IAsn1OctetString;
+begin
+ LOctetString := TAsn1OctetString.GetInstance(AEncoding);
+ CheckTrue(TArrayUtilities.AreEqual(AExpectedOctets, LOctetString.GetOctets()), AMessage);
+end;
+
+procedure TAsn1GeneratorTest.CheckTaggedOctetStringEncoding(const AEncoding: TCryptoLibByteArray;
+ AExpectedTagNo: Int32; ADeclaredExplicit: Boolean; const AExpectedOctets: TCryptoLibByteArray;
+ const AMessage: String);
+var
+ LTaggedObject: IAsn1TaggedObject;
+ LOctetString: IAsn1OctetString;
+begin
+ LTaggedObject := TAsn1TaggedObject.GetInstance(AEncoding);
+ CheckTrue(LTaggedObject.HasContextTag(AExpectedTagNo),
+ 'octets tagNo [' + IntToStr(AExpectedTagNo) + ']');
+
+ LOctetString := TAsn1OctetString.GetInstance(LTaggedObject, ADeclaredExplicit);
+ CheckTrue(TArrayUtilities.AreEqual(AExpectedOctets, LOctetString.GetOctets()), AMessage);
+end;
+
+procedure TAsn1GeneratorTest.TestTaggedBerSequence(ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const ASeq: IAsn1Sequence);
+var
+ LBOut: TMemoryStream;
+ LGen: IBerSequenceGenerator;
+ LExpected, LActual: TCryptoLibByteArray;
+ LTagged: IAsn1TaggedObject;
+begin
+ LBOut := TMemoryStream.Create();
+ try
+ LGen := TBerSequenceGenerator.Create(LBOut, ATagNo, ADeclaredExplicit);
+ AddSequenceContents(LGen);
+ LGen.Close();
+
+ LTagged := TBerTaggedObject.Create(ADeclaredExplicit, ATagNo, ASeq);
+ LExpected := LTagged.GetEncoded();
+ LBOut.Position := 0;
+ LActual := TStreamUtilities.ReadAll(LBOut);
+
+ CheckTrue(AreEqual(LExpected, LActual),
+ 'BER seq [' + IntToStr(ATagNo) + '] explicit=' + SysUtils.BoolToStr(ADeclaredExplicit, True));
+
+ CheckSequenceRoundTrip(LActual, ATagNo, ADeclaredExplicit, ASeq);
+ finally
+ LBOut.Free;
+ end;
+end;
+
+procedure TAsn1GeneratorTest.TestTaggedDerSequence(ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const ASeq: IAsn1Sequence);
+var
+ LBOut: TMemoryStream;
+ LGen: IDerSequenceGenerator;
+ LExpected, LActual: TCryptoLibByteArray;
+ LTagged: IAsn1TaggedObject;
+begin
+ LBOut := TMemoryStream.Create();
+ try
+ LGen := TDerSequenceGenerator.Create(LBOut, ATagNo, ADeclaredExplicit);
+ AddSequenceContents(LGen);
+ LGen.Close();
+
+ LTagged := TDerTaggedObject.Create(ADeclaredExplicit, ATagNo, ASeq);
+ LExpected := LTagged.GetEncoded(TAsn1Encodable.Der);
+ LBOut.Position := 0;
+ LActual := TStreamUtilities.ReadAll(LBOut);
+
+ CheckTrue(AreEqual(LExpected, LActual),
+ 'DER seq [' + IntToStr(ATagNo) + '] explicit=' + SysUtils.BoolToStr(ADeclaredExplicit, True));
+
+ CheckSequenceRoundTrip(LActual, ATagNo, ADeclaredExplicit, ASeq);
+ finally
+ LBOut.Free;
+ end;
+end;
+
+procedure TAsn1GeneratorTest.TestTaggedBerOctetString(ATagNo: Int32; ADeclaredExplicit: Boolean;
+ const AOctets: TCryptoLibByteArray);
+var
+ LBOut: TMemoryStream;
+ LGen: IBerOctetStringGenerator;
+ LActual: TCryptoLibByteArray;
+begin
+ LBOut := TMemoryStream.Create();
+ try
+ LGen := TBerOctetStringGenerator.Create(LBOut, ATagNo, ADeclaredExplicit);
+ WriteOctets(LGen, AOctets);
+ LGen.Close();
+
+ LBOut.Position := 0;
+ LActual := TStreamUtilities.ReadAll(LBOut);
+
+ CheckTaggedOctetStringEncoding(LActual, ATagNo, ADeclaredExplicit, AOctets,
+ 'BER octets [' + IntToStr(ATagNo) + '] explicit=' + SysUtils.BoolToStr(ADeclaredExplicit, True));
+ finally
+ LBOut.Free;
+ end;
+end;
+
+procedure TAsn1GeneratorTest.TestAll;
+var
+ LContent, LActual: TCryptoLibByteArray;
+ LVector: IAsn1EncodableVector;
+ LBerSeq, LDerSeq: IAsn1Sequence;
+ LBOut: TMemoryStream;
+ LBerSeqGen: IBerSequenceGenerator;
+ LDerSeqGen: IDerSequenceGenerator;
+ LBerOctGen: IBerOctetStringGenerator;
+ LI: Int32;
+begin
+ System.SetLength(LContent, 2500);
+ for LI := 0 to System.Length(LContent) - 1 do
+ LContent[LI] := Byte(LI);
+
+ LVector := TAsn1EncodableVector.Create();
+ LVector.Add(TDerInteger.ValueOf(4095));
+ LVector.Add(TDerOctetString.FromContents(TCryptoLibByteArray.Create(1, 2, 3, 4)));
+
+ LBerSeq := TBerSequence.FromVector(LVector);
+ LDerSeq := TDerSequence.FromVector(LVector);
+
+ LBOut := TMemoryStream.Create();
+ try
+ LBerSeqGen := TBerSequenceGenerator.Create(LBOut);
+ AddSequenceContents(LBerSeqGen);
+ LBerSeqGen.Close();
+
+ LBOut.Position := 0;
+ LActual := TStreamUtilities.ReadAll(LBOut);
+ CheckTrue(AreEqual(LBerSeq.GetEncoded(), LActual), 'untagged BER seq');
+ finally
+ LBOut.Free;
+ end;
+
+ LBOut := TMemoryStream.Create();
+ try
+ LDerSeqGen := TDerSequenceGenerator.Create(LBOut);
+ AddSequenceContents(LDerSeqGen);
+ LDerSeqGen.Close();
+
+ LBOut.Position := 0;
+ LActual := TStreamUtilities.ReadAll(LBOut);
+ CheckTrue(AreEqual(LDerSeq.GetEncoded(TAsn1Encodable.Der), LActual), 'untagged DER seq');
+ finally
+ LBOut.Free;
+ end;
+
+ LBOut := TMemoryStream.Create();
+ try
+ LBerOctGen := TBerOctetStringGenerator.Create(LBOut);
+ WriteOctets(LBerOctGen, LContent);
+ LBerOctGen.Close();
+
+ LBOut.Position := 0;
+ LActual := TStreamUtilities.ReadAll(LBOut);
+ CheckBerOctetStringEncoding(LActual, LContent, 'untagged BER octets');
+ finally
+ LBOut.Free;
+ end;
+
+ for LI := 0 to System.Length(TAG_NOS) - 1 do
+ begin
+ TestTaggedBerSequence(TAG_NOS[LI], True, LBerSeq);
+ TestTaggedBerSequence(TAG_NOS[LI], False, LBerSeq);
+ TestTaggedDerSequence(TAG_NOS[LI], True, LDerSeq);
+ TestTaggedDerSequence(TAG_NOS[LI], False, LDerSeq);
+ TestTaggedBerOctetString(TAG_NOS[LI], True, LContent);
+ TestTaggedBerOctetString(TAG_NOS[LI], False, LContent);
+ end;
+end;
+
+initialization
+
+{$IFDEF FPC}
+ RegisterTest(TAsn1GeneratorTest);
+{$ELSE}
+ RegisterTest(TAsn1GeneratorTest.Suite);
+{$ENDIF FPC}
+
+end.
diff --git a/CryptoLib.Tests/src/Asn1/Asn1SequenceParserTests.pas b/CryptoLib.Tests/src/Asn1/Asn1SequenceParserTests.pas
index e9fec13c..e138517c 100644
--- a/CryptoLib.Tests/src/Asn1/Asn1SequenceParserTests.pas
+++ b/CryptoLib.Tests/src/Asn1/Asn1SequenceParserTests.pas
@@ -210,7 +210,7 @@ procedure TTestAsn1SequenceParser.TestBerExplicitTaggedSequenceWriting;
try
SeqGen := TBerSequenceGenerator.Create(BOut, 1, True);
- SeqGen.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen.AddObject(TDerInteger.ValueOf(0));
SeqGen.AddObject(TDerObjectIdentifier.Create('1.1') as IDerObjectIdentifier);
@@ -276,7 +276,7 @@ procedure TTestAsn1SequenceParser.TestBerWriting;
try
SeqGen := TBerSequenceGenerator.Create(BOut);
- SeqGen.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen.AddObject(TDerInteger.ValueOf(0));
SeqGen.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
@@ -301,7 +301,7 @@ procedure TTestAsn1SequenceParser.TestDerExplicitTaggedSequenceWriting;
try
SeqGen := TDerSequenceGenerator.Create(BOut, 1, True);
- SeqGen.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen.AddObject(TDerInteger.ValueOf(0));
SeqGen.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
@@ -329,7 +329,7 @@ procedure TTestAsn1SequenceParser.TestDerImplicitTaggedSequenceWriting;
try
SeqGen := TDerSequenceGenerator.Create(BOut, 1, False);
- SeqGen.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen.AddObject(TDerInteger.ValueOf(0));
SeqGen.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
@@ -395,7 +395,7 @@ procedure TTestAsn1SequenceParser.TestDerWriting;
try
SeqGen := TDerSequenceGenerator.Create(BOut);
- SeqGen.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen.AddObject(TDerInteger.ValueOf(0));
SeqGen.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
@@ -426,15 +426,14 @@ procedure TTestAsn1SequenceParser.TestNestedBerDerWriting;
try
SeqGen1 := TBerSequenceGenerator.Create(bOut);
- SeqGen1.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen1.AddObject(TDerInteger.ValueOf(0));
SeqGen1.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
SeqGen2 := TDerSequenceGenerator.Create(seqGen1.GetRawOutputStream());
- SeqGen2.AddObject(TDerInteger.Create(TBigInteger.ValueOf(1))
- as IDerInteger);
+ SeqGen2.AddObject(TDerInteger.ValueOf(1));
SeqGen2.Close();
@@ -465,14 +464,14 @@ procedure TTestAsn1SequenceParser.TestNestedBerWriting;
try
SeqGen1 := TBerSequenceGenerator.Create(bOut);
- SeqGen1.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen1.AddObject(TDerInteger.ValueOf(0));
SeqGen1.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
SeqGen2 := TBerSequenceGenerator.Create(seqGen1.GetRawOutputStream());
- SeqGen2.AddObject(TDerInteger.Create(TBigInteger.ValueOf(1)) as IDerInteger);
+ SeqGen2.AddObject(TDerInteger.ValueOf(1));
SeqGen2.Close();
@@ -503,14 +502,14 @@ procedure TTestAsn1SequenceParser.TestNestedDerWriting;
try
SeqGen1 := TDerSequenceGenerator.Create(bOut);
- SeqGen1.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen1.AddObject(TDerInteger.ValueOf(0));
SeqGen1.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
SeqGen2 := TDerSequenceGenerator.Create(seqGen1.GetRawOutputStream());
- SeqGen2.AddObject(TDerInteger.Create(TBigInteger.One) as IDerInteger);
+ SeqGen2.AddObject(TDerInteger.ValueOf(1));
SeqGen2.Close();
@@ -536,7 +535,7 @@ procedure TTestAsn1SequenceParser.TestNestedExplicitTagDerWriting;
try
SeqGen1 := TDerSequenceGenerator.Create(bOut);
- SeqGen1.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen1.AddObject(TDerInteger.ValueOf(0));
SeqGen1.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
@@ -544,8 +543,7 @@ procedure TTestAsn1SequenceParser.TestNestedExplicitTagDerWriting;
SeqGen2 := TDerSequenceGenerator.Create
(seqGen1.GetRawOutputStream(), 1, True);
- SeqGen2.AddObject(TDerInteger.Create(TBigInteger.ValueOf(1))
- as IDerInteger);
+ SeqGen2.AddObject(TDerInteger.ValueOf(1));
SeqGen2.Close();
@@ -571,7 +569,7 @@ procedure TTestAsn1SequenceParser.TestNestedImplicitTagDerWriting;
try
SeqGen1 := TDerSequenceGenerator.Create(bOut);
- SeqGen1.AddObject(TDerInteger.Create(TBigInteger.Zero) as IDerInteger);
+ SeqGen1.AddObject(TDerInteger.ValueOf(0));
SeqGen1.AddObject(TDerObjectIdentifier.Create('1.1')
as IDerObjectIdentifier);
@@ -579,8 +577,7 @@ procedure TTestAsn1SequenceParser.TestNestedImplicitTagDerWriting;
SeqGen2 := TDerSequenceGenerator.Create(seqGen1.GetRawOutputStream(),
1, False);
- SeqGen2.AddObject(TDerInteger.Create(TBigInteger.ValueOf(1))
- as IDerInteger);
+ SeqGen2.AddObject(TDerInteger.ValueOf(1));
SeqGen2.Close();
@@ -614,7 +611,7 @@ procedure TTestAsn1SequenceParser.TestMaximumConstructedNestingDerExceedsLimit;
TAsn1InputStream.MaxConstructedDepth :=
TAsn1InputStream.DefaultMaxConstructedDepth;
- LInner := TDerInteger.Create(TBigInteger.Zero);
+ LInner := TDerInteger.ValueOf(0);
for LI := 1 to TAsn1InputStream.DefaultMaxConstructedDepth + 1 do
begin
LVec := TAsn1EncodableVector.Create();
diff --git a/CryptoLib.Tests/src/Asn1/Asn1TimeFormatTests.pas b/CryptoLib.Tests/src/Asn1/Asn1TimeFormatTests.pas
new file mode 100644
index 00000000..17861d0a
--- /dev/null
+++ b/CryptoLib.Tests/src/Asn1/Asn1TimeFormatTests.pas
@@ -0,0 +1,187 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit Asn1TimeFormatTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+ SysUtils,
+{$IFDEF FPC}
+ fpcunit,
+ testregistry,
+{$ELSE}
+ TestFramework,
+{$ENDIF FPC}
+ ClpAsn1Objects,
+ ClpIAsn1Objects,
+ CryptoLibTestBase;
+
+type
+
+ ///
+ /// ASN.1 UTCTime and GeneralizedTime accept/reject format tests.
+ ///
+ TAsn1TimeFormatTest = class(TCryptoLibAlgorithmTestCase)
+ private
+ class function IsValidUtcTime(const S: String): Boolean; static;
+ class function IsValidGeneralizedTime(const S: String): Boolean; static;
+ published
+ procedure TestValidUtcTime;
+ procedure TestInvalidUtcTimeFieldRanges;
+ procedure TestInvalidUtcTimeStructure;
+ procedure TestValidGeneralizedTime;
+ procedure TestInvalidGeneralizedTimeFieldRanges;
+ procedure TestInvalidGeneralizedTimeStructure;
+ ///
+ /// Exact content octets (tag/length stripped) of fuzzing-report inputs that were
+ /// previously accepted; every one must be rejected.
+ ///
+ procedure TestRejectsReportedCorpusContent;
+ end;
+
+implementation
+
+{ TAsn1TimeFormatTest }
+
+class function TAsn1TimeFormatTest.IsValidGeneralizedTime(const S: String): Boolean;
+var
+ LTime: IAsn1GeneralizedTime;
+begin
+ try
+ LTime := TAsn1GeneralizedTime.Create(S);
+ Result := True;
+ except
+ on E: Exception do
+ Result := False;
+ end;
+end;
+
+class function TAsn1TimeFormatTest.IsValidUtcTime(const S: String): Boolean;
+var
+ LTime: IAsn1UtcTime;
+begin
+ try
+ LTime := TAsn1UtcTime.Create(S);
+ Result := True;
+ except
+ on E: Exception do
+ Result := False;
+ end;
+end;
+
+procedure TAsn1TimeFormatTest.TestValidUtcTime;
+begin
+ // X.680 sec. 47: minutes mandatory, seconds optional, zone (Z or offset) mandatory.
+ CheckTrue(IsValidUtcTime('5001010000Z'), 'no seconds, Z');
+ CheckTrue(IsValidUtcTime('500101000000Z'), 'seconds, Z');
+ CheckTrue(IsValidUtcTime('5001010000+0500'), 'no seconds, offset');
+ CheckTrue(IsValidUtcTime('5001010000+0530'), 'no seconds, offset');
+ CheckTrue(IsValidUtcTime('500101000000-0830'), 'seconds, offset');
+ CheckTrue(IsValidUtcTime('991231235959Z'), 'boundary fields');
+ CheckTrue(IsValidUtcTime('000101120000Z'), 'year 00 is fine');
+end;
+
+procedure TAsn1TimeFormatTest.TestInvalidUtcTimeFieldRanges;
+begin
+ CheckFalse(IsValidUtcTime('000000000000Z'), 'month 00, day 00');
+ CheckFalse(IsValidUtcTime('000200000000Z'), 'day 00');
+ CheckFalse(IsValidUtcTime('241300000000Z'), 'month 13 (and day/... irrelevant)');
+ CheckFalse(IsValidUtcTime('240132000000Z'), 'day 32');
+ CheckFalse(IsValidUtcTime('240101240000Z'), 'hour 24');
+ CheckFalse(IsValidUtcTime('240101006000Z'), 'minute 60');
+ CheckFalse(IsValidUtcTime('240101000060Z'), 'second 60');
+ CheckFalse(IsValidUtcTime('240101000000+2460'), 'offset minute 60');
+ CheckFalse(IsValidUtcTime('5001010000+05'), 'no seconds, offset (no minutes)');
+ CheckFalse(IsValidUtcTime('500101000000+05'), 'seconds, offset (no minutes)');
+end;
+
+procedure TAsn1TimeFormatTest.TestInvalidUtcTimeStructure;
+begin
+ CheckFalse(IsValidUtcTime('240101000000'), 'no zone');
+ CheckFalse(IsValidUtcTime('24010100000Z'), 'illegal length 12');
+ CheckFalse(IsValidUtcTime('2401010000X'), 'bad terminator');
+ CheckFalse(IsValidUtcTime('2401010000+99XX'), 'non-digit offset');
+ CheckFalse(IsValidUtcTime(''), 'empty');
+ // embedded control byte where seconds digits are expected
+ CheckFalse(IsValidUtcTime('2401010000' + #7 + '0Z'), 'embedded control byte');
+ // high (negative) byte where a digit is expected
+ CheckFalse(IsValidUtcTime('24010' + #255 + '000000Z'), 'high byte in digits');
+end;
+
+procedure TAsn1TimeFormatTest.TestValidGeneralizedTime;
+begin
+ CheckTrue(IsValidGeneralizedTime('2024010100Z'), 'hour only, Z');
+ CheckTrue(IsValidGeneralizedTime('202401010000Z'), 'minute, Z');
+ CheckTrue(IsValidGeneralizedTime('20240101000000Z'), 'second, Z');
+ CheckTrue(IsValidGeneralizedTime('20240101000000.5Z'), 'fractional ''.''');
+ CheckTrue(IsValidGeneralizedTime('20240101000000,123Z'), 'fractional '',''');
+ CheckTrue(IsValidGeneralizedTime('20240101000000+05'), 'numeric offset (no minutes)');
+ CheckTrue(IsValidGeneralizedTime('20240101000000+0500'), 'numeric offset');
+ CheckTrue(IsValidGeneralizedTime('20240101000000+0530'), 'numeric offset');
+ CheckTrue(IsValidGeneralizedTime('20240101000000'), 'local, full');
+ CheckTrue(IsValidGeneralizedTime('2024010100'), 'local, hour only');
+ CheckTrue(IsValidGeneralizedTime('19500101000000Z'), '19500101000000Z');
+end;
+
+procedure TAsn1TimeFormatTest.TestInvalidGeneralizedTimeFieldRanges;
+begin
+ CheckFalse(IsValidGeneralizedTime('20240001000000Z'), 'month 00');
+ CheckFalse(IsValidGeneralizedTime('20241301000000Z'), 'month 13');
+ CheckFalse(IsValidGeneralizedTime('20240132000000Z'), 'day 32');
+ CheckFalse(IsValidGeneralizedTime('2024010124Z'), 'hour 24');
+ CheckFalse(IsValidGeneralizedTime('202401010060Z'), 'minute 60');
+ CheckFalse(IsValidGeneralizedTime('20240101000060Z'), 'second 60');
+end;
+
+procedure TAsn1TimeFormatTest.TestInvalidGeneralizedTimeStructure;
+begin
+ CheckFalse(IsValidGeneralizedTime('202401010'), 'length 9 < 10');
+ CheckFalse(IsValidGeneralizedTime('20240101000000.'), 'decimal mark, no digits');
+ CheckFalse(IsValidGeneralizedTime('2024010100ZZ'), 'trailing junk after Z');
+ CheckFalse(IsValidGeneralizedTime('20240101000000X'), 'bad trailing');
+ CheckFalse(IsValidGeneralizedTime('20240101000000+1'), 'truncated offset (no minutes)');
+ CheckFalse(IsValidGeneralizedTime('20240101000000+123'), 'truncated offset');
+ CheckFalse(IsValidGeneralizedTime('202401' + #10 + '01000000Z'), 'embedded control byte');
+end;
+
+procedure TAsn1TimeFormatTest.TestRejectsReportedCorpusContent;
+begin
+ // 170d 3030303030303030303030305a -> "000000000000Z"
+ CheckFalse(IsValidUtcTime('000000000000Z'), '000000000000Z');
+ // 170d 3030303230303030303030305a -> "000200000000Z"
+ CheckFalse(IsValidUtcTime('000200000000Z'), '000200000000Z');
+ // 180f 303430303031303030303030303030 -> "040001000000000"
+ CheckFalse(IsValidGeneralizedTime('040001000000000'), '040001000000000');
+ // 180f 30343030303130303030303030302e -> "04000100000000."
+ CheckFalse(IsValidGeneralizedTime('04000100000000.'), '04000100000000.');
+ // 180f 3034303030313030303030303030302a-derived "04000100000000*" (control/punct tail)
+ CheckFalse(IsValidGeneralizedTime('04000100000000*'), '04000100000000*');
+end;
+
+initialization
+
+{$IFDEF FPC}
+ RegisterTest(TAsn1TimeFormatTest);
+{$ELSE}
+ RegisterTest(TAsn1TimeFormatTest.Suite);
+{$ENDIF FPC}
+
+end.
diff --git a/CryptoLib.Tests/src/Asn1/X509/IdpRelativeNameTests.pas b/CryptoLib.Tests/src/Asn1/X509/IdpRelativeNameTests.pas
new file mode 100644
index 00000000..00f7c0f1
--- /dev/null
+++ b/CryptoLib.Tests/src/Asn1/X509/IdpRelativeNameTests.pas
@@ -0,0 +1,100 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit IdpRelativeNameTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+ SysUtils,
+{$IFDEF FPC}
+ fpcunit,
+ testregistry,
+{$ELSE}
+ TestFramework,
+{$ENDIF FPC}
+ ClpAsn1Objects,
+ ClpIAsn1Objects,
+ ClpIAsn1Core,
+ ClpIX509Asn1Objects,
+ ClpX509Asn1Objects,
+ CryptoLibTestBase;
+
+type
+
+ /// Tests for IssuingDistributionPoint relative names (ASN.1 encoding).
+ ///
+ /// Per RFC 5280 sec. 4.2.1.13, IssuingDistributionPoint's nameRelativeToCRLIssuer is a single
+ /// RelativeDistinguishedName (a SET of AttributeTypeAndValue) that, per sec. 5.2.5, is appended as one element
+ /// to the CRL issuer's RDNSequence to form the full distribution-point DN.
+ ///
+ TIdpRelativeNameTest = class(TCryptoLibAlgorithmTestCase)
+ published
+ procedure TestSequenceShapedRelativeNameRejected;
+ end;
+
+implementation
+
+{ TIdpRelativeNameTest }
+
+procedure TIdpRelativeNameTest.TestSequenceShapedRelativeNameRejected;
+var
+ LName: IX509Name;
+ LInner: IAsn1Encodable;
+ LTagged: IAsn1TaggedObject;
+ LDpName: IDistributionPointName;
+ LRejected: Boolean;
+begin
+ LName := TX509Name.Create('O=ExampleOrg,OU=Test');
+ LInner := LName.ToAsn1Object() as IAsn1Encodable;
+ LTagged := TDerTaggedObject.Create(False, TDistributionPointName.NameRelativeToCrlIssuer, LInner);
+
+ LRejected := False;
+ try
+ LDpName := TDistributionPointName.GetOptional(LTagged);
+ if LDpName = nil then
+ LRejected := True;
+ except
+ on E: Exception do
+ LRejected := True;
+ end;
+ if not LRejected then
+ Fail('sequence-shaped nameRelativeToCRLIssuer accepted by GetOptional');
+
+ LRejected := False;
+ try
+ TDistributionPointName.GetInstance(LTagged, False);
+ except
+ on E: Exception do
+ LRejected := True;
+ end;
+ if not LRejected then
+ Fail('sequence-shaped nameRelativeToCRLIssuer accepted by GetInstance');
+end;
+
+initialization
+
+{$IFDEF FPC}
+RegisterTest(TIdpRelativeNameTest);
+{$ELSE}
+RegisterTest(TIdpRelativeNameTest.Suite);
+{$ENDIF FPC}
+
+end.
diff --git a/CryptoLib.Tests/src/Asn1/X509/X509NameTests.pas b/CryptoLib.Tests/src/Asn1/X509/X509NameTests.pas
index d13fd2b7..340a8814 100644
--- a/CryptoLib.Tests/src/Asn1/X509/X509NameTests.pas
+++ b/CryptoLib.Tests/src/Asn1/X509/X509NameTests.pas
@@ -34,6 +34,9 @@ interface
ClpIAsn1Objects,
ClpX509Asn1Objects,
ClpIX509Asn1Objects,
+ ClpAsn1Objects,
+ ClpIetfUtilities,
+ ClpX509DefaultEntryConverter,
ClpCryptoLibTypes,
CryptoLibTestBase;
@@ -60,15 +63,15 @@ TX509NameTest = class(TCryptoLibAlgorithmTestCase)
procedure TestInvalidHexDnFailsAtConstruction;
procedure TestCountryCodeLength;
procedure TestDnQualifierAttributeAliases;
+ procedure TestStateOrProvinceAttributeAliases;
+ procedure TestHexEscapedUtf8Parse;
+ procedure TestEscapeRoundTrip;
+ procedure TestInvariantCaseFolding;
end;
implementation
-uses
- ClpAsn1Objects,
- ClpX509DefaultEntryConverter;
-
{ TX509NameTest }
procedure TX509NameTest.SetUpTestData;
@@ -338,6 +341,191 @@ procedure TX509NameTest.TestDnQualifierAttributeAliases;
end;
end;
+procedure TX509NameTest.TestStateOrProvinceAttributeAliases;
+var
+ LAliases: array [0 .. 3] of String;
+ LName: IX509Name;
+ LList: TCryptoLibStringArray;
+ I: Int32;
+begin
+ LAliases[0] := 'ST';
+ LAliases[1] := 'st';
+ LAliases[2] := 'S';
+ LAliases[3] := 's';
+
+ for I := Low(LAliases) to High(LAliases) do
+ begin
+ LName := TX509Name.Create('CN=Foo,' + LAliases[I] + '=California');
+ LList := LName.GetValueList(TX509Name.ST);
+ CheckEquals(Int32(1), Int32(System.Length(LList)),
+ 'Alias ''' + LAliases[I] + ''' did not parse to a single stateOrProvinceName RDN');
+ CheckEquals('California', LList[0],
+ 'unexpected stateOrProvinceName value for alias ''' + LAliases[I] + '''');
+ end;
+
+ LName := TX509Name.Create('CN=Foo,S=California');
+ CheckEquals('CN=Foo,ST=California', LName.ToString(),
+ '''S'' alias did not normalise to ST on output');
+end;
+
+procedure TX509NameTest.TestHexEscapedUtf8Parse;
+var
+ LSubjects: array [0 .. 3] of String;
+ LExpectedValues: array [0 .. 3] of String;
+ I: Int32;
+ LName, LReparsed: IX509Name;
+ LVal, LReVal: String;
+begin
+ LSubjects[0] := 'CN=Lu\C4\8Di\C4\87';
+ LSubjects[1] := 'CN=M\C3\B6rsky';
+ LSubjects[2] := 'CN=\E6\97\A5\E6\9C\AC';
+ LSubjects[3] := 'CN=Lu\C4\8Di\C4\87,O=Acme';
+
+ LExpectedValues[0] := 'Lučić';
+ LExpectedValues[1] := 'Mörsky';
+ LExpectedValues[2] := '日本';
+ LExpectedValues[3] := 'Lučić';
+
+ for I := Low(LSubjects) to High(LSubjects) do
+ begin
+ LName := TX509Name.Create(LSubjects[I]);
+ LVal := LName.GetValueList(TX509Name.CN)[0];
+ CheckEquals(LExpectedValues[I], LVal,
+ 'unexpected CN value for ' + LSubjects[I]);
+
+ LReparsed := FromBytes(LName.GetEncoded());
+ LReVal := LReparsed.GetValueList(TX509Name.CN)[0];
+ CheckEquals(LExpectedValues[I], LReVal,
+ 'round-trip lost data for ' + LSubjects[I]);
+ end;
+
+ // Lone leading byte without continuation is malformed UTF-8.
+ // TODO: Enable on FPC when TEncoding.UTF8 rejects invalid sequences (currently lenient;
+ // lone $C4 decodes as '?' instead of throwing). Delphi: expect EEncodingError.
+{$IFNDEF FPC}
+ try
+ TX509Name.Create('CN=Lu\C4');
+ Fail('malformed UTF-8 escape sequence not rejected');
+ except
+ on E: EEncodingError do
+ ; // expected
+ end;
+{$ENDIF FPC}
+end;
+
+procedure TX509NameTest.TestEscapeRoundTrip;
+const
+ CASE_COUNT = 15;
+var
+ LInputs: array [0 .. CASE_COUNT - 1] of String;
+ LValues: array [0 .. CASE_COUNT - 1] of String;
+ LStrings: array [0 .. CASE_COUNT - 1] of String;
+ LMalformed: array [0 .. 10] of String;
+ I: Int32;
+ LName, LReparsed: IX509Name;
+ LEmpty: IX509Name;
+begin
+ LInputs[0] := 'CN=a\,b';
+ LInputs[1] := 'CN=a\;b';
+ LInputs[2] := 'CN=a\ * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit BinPolyTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+ SysUtils,
+{$IFDEF FPC}
+ fpcunit,
+ testregistry,
+{$ELSE}
+ TestFramework,
+{$ENDIF FPC}
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpIBinPolyInv,
+ ClpBinPolys,
+ ClpNat,
+ ClpIRandom,
+ ClpRandom,
+ ClpBinPolyScalarBackend,
+ ClpBinPolyX86V128Backend,
+ ClpBinPolyMulBaseBinomialReduce,
+ CryptoLibTestBase;
+
+type
+ TBinCase = record
+ CaseName: string;
+ N: Int32;
+ end;
+
+ TTrinCase = record
+ CaseName: string;
+ N: Int32;
+ K: Int32;
+ end;
+
+ TPentaCase = record
+ CaseName: string;
+ N: Int32;
+ K1: Int32;
+ K2: Int32;
+ K3: Int32;
+ end;
+
+ TTestBinPoly = class(TCryptoLibAlgorithmTestCase)
+ strict private
+ const
+ BikeR1 = 12323;
+ RandomTrials = 16;
+ FixedSeed = $10101010;
+ OffX = 3;
+ OffY = 5;
+ OffZ = 7;
+ OffPadTail = 4;
+
+ procedure AssertUInt64ArraysEqual(ASize: Int32;
+ const AExpected, AActual: TCryptoLibUInt64Array; const AContext: string);
+ procedure AssertSliceEquals(const AExpected: TCryptoLibUInt64Array;
+ const AActual: TCryptoLibUInt64Array; AActualOff, ASize: Int32;
+ const AContext: string);
+ procedure AssertGuardZonesEqual(const ABefore, AAfter: TCryptoLibUInt64Array;
+ ASliceOff, ASliceSize: Int32; const AContext: string);
+ function PadBuffer(ASliceSize, ASliceOff, APadTail: Int32;
+ const ARandom: IRandom): TCryptoLibUInt64Array;
+ function RandomLimbs(const ARandom: IRandom; ASize: Int32)
+ : TCryptoLibUInt64Array;
+ function RandomReduced(const ARandom: IRandom; AN: Int32)
+ : TCryptoLibUInt64Array;
+ function ReferenceBitLength(ASize: Int32;
+ const AX: TCryptoLibUInt64Array): Int32;
+ function CarrylessMul(AN: Int32; const AX, AY: TCryptoLibUInt64Array)
+ : TCryptoLibUInt64Array;
+ function ReferenceBinomialMul(AR: Int32; const AX, AY: TCryptoLibUInt64Array)
+ : TCryptoLibUInt64Array;
+ function ReferenceTrinomialMul(AN, AK: Int32;
+ const AX, AY: TCryptoLibUInt64Array): TCryptoLibUInt64Array;
+ function ReferencePentanomialMul(AN, AK1, AK2, AK3: Int32;
+ const AX, AY: TCryptoLibUInt64Array): TCryptoLibUInt64Array;
+ procedure RunAllOpsAtOffsets(const AMul: IBinPolyMul; AN: Int32;
+ const ARandom: IRandom; const ALabel: string);
+ procedure RunInvertChecks(const AMul: IBinPolyMul; const AInv: IBinPolyInv;
+ AN: Int32; const ARandom: IRandom; const ALabel: string);
+ procedure RunX86V128VsScalar(AN: Int32; const ARandom: IRandom;
+ const AContext: string);
+ procedure AssertX86V128MultiplyEquals(AN: Int32;
+ const AX, AY: TCryptoLibUInt64Array; const AContext: string);
+ published
+ procedure TestBinomial_Add_AgainstXor_BikeR1;
+ procedure TestBinomial_AddTo_AgainstXor_BikeR1;
+ procedure TestBinomial_Multiply_AgainstReference_BikeR1;
+ procedure TestBinomial_Multiply_AgainstReference_Small;
+ procedure TestBinomial_Square_AgainstReference_Even;
+ procedure TestBinomial_Multiply_MultiplyByZero_BikeR1;
+ procedure TestBinomial_Multiply_MultiplyByOne_BikeR1;
+ procedure TestBinomial_Square_AgainstReferenceMultiplyBySelf_BikeR1;
+ procedure TestBinomial_SquareN_AgainstRepeatedSquare_BikeR1;
+ procedure TestBinomial_SquareN_ZeroNThrows_BikeR1;
+ procedure TestBinomial_AllOps_NonZeroOffsets;
+ procedure TestTrinomial_Multiply_AgainstReference;
+ procedure TestTrinomial_Multiply_MultiplyByZero;
+ procedure TestTrinomial_Multiply_MultiplyByOne;
+ procedure TestTrinomial_Square_AgainstReferenceMultiplyBySelf;
+ procedure TestTrinomial_SquareN_AgainstRepeatedSquare;
+ procedure TestTrinomial_AllOps_NonZeroOffsets;
+ procedure TestPentanomial_Multiply_AgainstReference;
+ procedure TestPentanomial_Multiply_MultiplyByZero;
+ procedure TestPentanomial_Multiply_MultiplyByOne;
+ procedure TestPentanomial_Square_AgainstReferenceMultiplyBySelf;
+ procedure TestPentanomial_SquareN_AgainstRepeatedSquare;
+ procedure TestPentanomial_AllOps_NonZeroOffsets;
+ procedure TestFactory_RejectsInvalidParameters;
+ procedure TestFactory_AcceptsEvenN;
+ procedure TestTrinomial_Invert_RoundTrip;
+ procedure TestPentanomial_Invert_RoundTrip;
+ procedure TestInv_Factory_RejectsNullAndDegenerate;
+ procedure TestBitLengthVar_AgainstReference;
+ procedure TestX86V128_Multiply_MatchesScalar;
+ procedure TestX86V128_SizeSweep;
+ procedure TestX86V128_LSize10_MidWindow;
+ procedure TestX86V128_SmallSizes_AllOps;
+ procedure TestX86V128_MultiplyByZeroAndOne;
+ procedure TestX86V128_EdgeVectors;
+ end;
+
+implementation
+
+const
+ TrinomialCases: array [0 .. 36] of TTrinCase = (
+ (CaseName: 'evenTrin_n130_k5'; N: 130; K: 5),
+ (CaseName: 'evenTrin_n160_k7'; N: 160; K: 7),
+ (CaseName: 'evenTrin_n200_k70'; N: 200; K: 70),
+ (CaseName: 'evenTrin_n64_k5'; N: 64; K: 5),
+ (CaseName: 'evenTrin_n128_k64'; N: 128; K: 64),
+ (CaseName: 'evenTrin_n128_k7'; N: 128; K: 7),
+ (CaseName: 'evenTrin_n192_k65'; N: 192; K: 65),
+ (CaseName: 'evenTrin_n256_k9'; N: 256; K: 9),
+ (CaseName: 'evenTrin_n256_k127'; N: 256; K: 127),
+ (CaseName: 'sect113'; N: 113; K: 9),
+ (CaseName: 'sect193'; N: 193; K: 15),
+ (CaseName: 'sect233'; N: 233; K: 74),
+ (CaseName: 'sect239'; N: 239; K: 158),
+ (CaseName: 'sect409'; N: 409; K: 87),
+ (CaseName: 'trinA_n257_k1'; N: 257; K: 1),
+ (CaseName: 'trinA_n383_k29'; N: 383; K: 29),
+ (CaseName: 'trinA_n767_k7'; N: 767; K: 7),
+ (CaseName: 'trinA3_n65_k1'; N: 65; K: 1),
+ (CaseName: 'trinA3_n95_k1'; N: 95; K: 1),
+ (CaseName: 'trinA5_n129_k1'; N: 129; K: 1),
+ (CaseName: 'trinA5_n159_k1'; N: 159; K: 1),
+ (CaseName: 'trinA6_n161_k1'; N: 161; K: 1),
+ (CaseName: 'trinA6_n191_k5'; N: 191; K: 5),
+ (CaseName: 'trinA8_n225_k1'; N: 225; K: 1),
+ (CaseName: 'trinA8_n255_k5'; N: 255; K: 5),
+ (CaseName: 'trinB_n129_k64'; N: 129; K: 64),
+ (CaseName: 'trinB_n257_k128'; N: 257; K: 128),
+ (CaseName: 'trinB_n513_k128'; N: 513; K: 128),
+ (CaseName: 'trinC5_n129_k65'; N: 129; K: 65),
+ (CaseName: 'trinC5_n159_k95'; N: 159; K: 95),
+ (CaseName: 'trinC6_n161_k65'; N: 161; K: 65),
+ (CaseName: 'trinC6_n191_k127'; N: 191; K: 127),
+ (CaseName: 'trinC7_n193_k65'; N: 193; K: 65),
+ (CaseName: 'trinC7_n223_k159'; N: 223; K: 159),
+ (CaseName: 'trinD_n65_k2'; N: 65; K: 2),
+ (CaseName: 'trinD_n127_k70'; N: 127; K: 70),
+ (CaseName: 'trinD_n193_k140'; N: 193; K: 140));
+
+ PentanomialCases: array [0 .. 30] of TPentaCase = (
+ (CaseName: 'penta64_n64_k1_2_3'; N: 64; K1: 1; K2: 2; K3: 3),
+ (CaseName: 'penta64_n128_k2_5_7'; N: 128; K1: 2; K2: 5; K3: 7),
+ (CaseName: 'penta64_n256_k5_7_12'; N: 256; K1: 5; K2: 7; K3: 12),
+ (CaseName: 'penta64_n256_k1_65_130'; N: 256; K1: 1; K2: 65; K3: 130),
+ (CaseName: 'penta64_n256_k1_64_130'; N: 256; K1: 1; K2: 64; K3: 130),
+ (CaseName: 'sect131'; N: 131; K1: 2; K2: 3; K3: 8),
+ (CaseName: 'sect163'; N: 163; K1: 3; K2: 6; K3: 7),
+ (CaseName: 'sect283'; N: 283; K1: 5; K2: 7; K3: 12),
+ (CaseName: 'sect571'; N: 571; K1: 2; K2: 5; K3: 10),
+ (CaseName: 'pentaA3_n67_k1_2_3'; N: 67; K1: 1; K2: 2; K3: 3),
+ (CaseName: 'pentaA3_n95_k15_25_31'; N: 95; K1: 15; K2: 25; K3: 31),
+ (CaseName: 'pentaA4_n97_k1_2_3'; N: 97; K1: 1; K2: 2; K3: 3),
+ (CaseName: 'pentaA4_n127_k5_20_63'; N: 127; K1: 5; K2: 20; K3: 63),
+ (CaseName: 'pentaA7_n193_k1_2_3'; N: 193; K1: 1; K2: 2; K3: 3),
+ (CaseName: 'pentaA7_n223_k30_50_63'; N: 223; K1: 30; K2: 50; K3: 63),
+ (CaseName: 'pentaA8_n225_k1_2_3'; N: 225; K1: 1; K2: 2; K3: 3),
+ (CaseName: 'pentaA8_n255_k5_20_63'; N: 255; K1: 5; K2: 20; K3: 63),
+ (CaseName: 'pentaB_n193_k1_65_67'; N: 193; K1: 1; K2: 65; K3: 67),
+ (CaseName: 'pentaB_n513_k10_70_200'; N: 513; K1: 10; K2: 70; K3: 200),
+ (CaseName: 'pentaB_n513_k63_70_300'; N: 513; K1: 63; K2: 70; K3: 300),
+ (CaseName: 'pentaC_n129_k1_2_66'; N: 129; K1: 1; K2: 2; K3: 66),
+ (CaseName: 'pentaC_n193_k1_2_64'; N: 193; K1: 1; K2: 2; K3: 64),
+ (CaseName: 'pentaC_n257_k64_65_130'; N: 257; K1: 64; K2: 65; K3: 130),
+ (CaseName: 'pentaD_n129_k1_2_65'; N: 129; K1: 1; K2: 2; K3: 65),
+ (CaseName: 'pentaD_n257_k3_33_130'; N: 257; K1: 3; K2: 33; K3: 130),
+ (CaseName: 'pentaD_n513_k10_63_200'; N: 513; K1: 10; K2: 63; K3: 200),
+ (CaseName: 'c2pnb176w1'; N: 176; K1: 1; K2: 2; K3: 43),
+ (CaseName: 'c2pnb208w1'; N: 208; K1: 1; K2: 2; K3: 83),
+ (CaseName: 'c2pnb272w1'; N: 272; K1: 1; K2: 3; K3: 56),
+ (CaseName: 'c2pnb304w1'; N: 304; K1: 1; K2: 2; K3: 11),
+ (CaseName: 'c2pnb368w1'; N: 368; K1: 1; K2: 2; K3: 85));
+
+ SectTrinomialCases: array [0 .. 4] of TTrinCase = (
+ (CaseName: 'sect113'; N: 113; K: 9),
+ (CaseName: 'sect193'; N: 193; K: 15),
+ (CaseName: 'sect233'; N: 233; K: 74),
+ (CaseName: 'sect239'; N: 239; K: 158),
+ (CaseName: 'sect409'; N: 409; K: 87));
+
+ SectPentanomialCases: array [0 .. 3] of TPentaCase = (
+ (CaseName: 'sect131'; N: 131; K1: 2; K2: 3; K3: 8),
+ (CaseName: 'sect163'; N: 163; K1: 3; K2: 6; K3: 7),
+ (CaseName: 'sect283'; N: 283; K1: 5; K2: 7; K3: 12),
+ (CaseName: 'sect571'; N: 571; K1: 2; K2: 5; K3: 10));
+
+ X962EvenPentanomialCases: array [0 .. 4] of TPentaCase = (
+ (CaseName: 'c2pnb176w1'; N: 176; K1: 1; K2: 2; K3: 43),
+ (CaseName: 'c2pnb208w1'; N: 208; K1: 1; K2: 2; K3: 83),
+ (CaseName: 'c2pnb272w1'; N: 272; K1: 1; K2: 3; K3: 56),
+ (CaseName: 'c2pnb304w1'; N: 304; K1: 1; K2: 2; K3: 11),
+ (CaseName: 'c2pnb368w1'; N: 368; K1: 1; K2: 2; K3: 85));
+
+{ TTestBinPoly }
+
+procedure TTestBinPoly.AssertUInt64ArraysEqual(ASize: Int32;
+ const AExpected, AActual: TCryptoLibUInt64Array; const AContext: string);
+begin
+ Check(TBinPolys.EqualTo(ASize, AExpected, 0, AActual, 0) <> 0, AContext);
+end;
+
+procedure TTestBinPoly.AssertSliceEquals(const AExpected: TCryptoLibUInt64Array;
+ const AActual: TCryptoLibUInt64Array; AActualOff, ASize: Int32;
+ const AContext: string);
+var
+ LI: Int32;
+begin
+ for LI := 0 to ASize - 1 do
+ CheckEquals(AExpected[LI], AActual[AActualOff + LI], AContext + ' limb ' + IntToStr(LI));
+end;
+
+procedure TTestBinPoly.AssertGuardZonesEqual(const ABefore, AAfter: TCryptoLibUInt64Array;
+ ASliceOff, ASliceSize: Int32; const AContext: string);
+var
+ LI: Int32;
+begin
+ for LI := 0 to ASliceOff - 1 do
+ CheckEquals(ABefore[LI], AAfter[LI], AContext + ' head guard at ' + IntToStr(LI));
+ for LI := ASliceOff + ASliceSize to System.Length(AAfter) - 1 do
+ CheckEquals(ABefore[LI], AAfter[LI], AContext + ' tail guard at ' + IntToStr(LI));
+end;
+
+function TTestBinPoly.PadBuffer(ASliceSize, ASliceOff, APadTail: Int32;
+ const ARandom: IRandom): TCryptoLibUInt64Array;
+var
+ LTotal, LI, LJ: Int32;
+ LBytes: TBytes;
+ LW: UInt64;
+begin
+ LTotal := ASliceOff + ASliceSize + APadTail;
+ System.SetLength(Result, LTotal);
+ System.SetLength(LBytes, LTotal shl 3);
+ ARandom.NextBytes(LBytes);
+ for LI := 0 to LTotal - 1 do
+ begin
+ LW := 0;
+ for LJ := 0 to 7 do
+ LW := LW or (UInt64(LBytes[(LI shl 3) + LJ]) shl (LJ shl 3));
+ Result[LI] := LW;
+ end;
+end;
+
+function TTestBinPoly.RandomLimbs(const ARandom: IRandom; ASize: Int32)
+ : TCryptoLibUInt64Array;
+var
+ LI, LJ: Int32;
+ LBytes: TBytes;
+ LW: UInt64;
+begin
+ System.SetLength(Result, ASize);
+ System.SetLength(LBytes, ASize shl 3);
+ ARandom.NextBytes(LBytes);
+ for LI := 0 to ASize - 1 do
+ begin
+ LW := 0;
+ for LJ := 0 to 7 do
+ LW := LW or (UInt64(LBytes[(LI shl 3) + LJ]) shl (LJ shl 3));
+ Result[LI] := LW;
+ end;
+end;
+
+function TTestBinPoly.RandomReduced(const ARandom: IRandom; AN: Int32)
+ : TCryptoLibUInt64Array;
+var
+ LSize, LPartial, LI, LJ: Int32;
+ LBytes: TBytes;
+ LW: UInt64;
+begin
+ LSize := (AN + 63) shr 6;
+ System.SetLength(Result, LSize);
+ System.SetLength(LBytes, LSize shl 3);
+ ARandom.NextBytes(LBytes);
+ for LI := 0 to LSize - 1 do
+ begin
+ LW := 0;
+ for LJ := 0 to 7 do
+ LW := LW or (UInt64(LBytes[(LI shl 3) + LJ]) shl (LJ shl 3));
+ Result[LI] := LW;
+ end;
+ LPartial := AN and 63;
+ if LPartial <> 0 then
+ Result[LSize - 1] := Result[LSize - 1] and ((UInt64(1) shl LPartial) - 1);
+end;
+
+function TTestBinPoly.ReferenceBitLength(ASize: Int32;
+ const AX: TCryptoLibUInt64Array): Int32;
+var
+ LBit: Int32;
+begin
+ for LBit := (ASize shl 6) - 1 downto 0 do
+ if ((AX[LBit shr 6] shr (LBit and 63)) and 1) <> 0 then
+ Exit(LBit + 1);
+ Result := 0;
+end;
+
+function TTestBinPoly.CarrylessMul(AN: Int32; const AX, AY: TCryptoLibUInt64Array)
+ : TCryptoLibUInt64Array;
+var
+ LSize, LI, LWOff, LBOff, LJ: Int32;
+ LYj: UInt64;
+begin
+ LSize := (AN + 63) shr 6;
+ System.SetLength(Result, 2 * LSize);
+ TBinPolys.Zero(2 * LSize, Result, 0);
+ for LI := 0 to AN - 1 do
+ begin
+ if ((AX[LI shr 6] shr (LI and 63)) and 1) = 0 then
+ Continue;
+ LWOff := LI shr 6;
+ LBOff := LI and 63;
+ if LBOff = 0 then
+ begin
+ for LJ := 0 to LSize - 1 do
+ Result[LWOff + LJ] := Result[LWOff + LJ] xor AY[LJ];
+ end
+ else
+ begin
+ for LJ := 0 to LSize - 1 do
+ begin
+ LYj := AY[LJ];
+ Result[LWOff + LJ] := Result[LWOff + LJ] xor (LYj shl LBOff);
+ Result[LWOff + LJ + 1] := Result[LWOff + LJ + 1] xor (LYj shr (64 - LBOff));
+ end;
+ end;
+ end;
+end;
+
+function TTestBinPoly.ReferenceBinomialMul(AR: Int32;
+ const AX, AY: TCryptoLibUInt64Array): TCryptoLibUInt64Array;
+var
+ LSize, LP, LQ, LPartial: Int32;
+ LPartialMask: UInt64;
+ LZz: TCryptoLibUInt64Array;
+begin
+ LSize := (AR + 63) shr 6;
+ LZz := CarrylessMul(AR, AX, AY);
+ System.SetLength(Result, LSize);
+ TNat.Copy64(LSize, LZz, 0, Result, 0);
+ for LP := AR to 2 * AR - 2 do
+ begin
+ if ((LZz[LP shr 6] shr (LP and 63)) and 1) = 0 then
+ Continue;
+ LQ := LP - AR;
+ Result[LQ shr 6] := Result[LQ shr 6] xor (UInt64(1) shl (LQ and 63));
+ end;
+ LPartial := AR and 63;
+ if LPartial = 0 then
+ LPartialMask := High(UInt64)
+ else
+ LPartialMask := (UInt64(1) shl LPartial) - 1;
+ Result[LSize - 1] := Result[LSize - 1] and LPartialMask;
+end;
+
+function TTestBinPoly.ReferenceTrinomialMul(AN, AK: Int32;
+ const AX, AY: TCryptoLibUInt64Array): TCryptoLibUInt64Array;
+var
+ LSize, LP, LQ0, LQ1, LPartial: Int32;
+ LPartialMask: UInt64;
+ LZz: TCryptoLibUInt64Array;
+begin
+ LSize := (AN + 63) shr 6;
+ LZz := CarrylessMul(AN, AX, AY);
+ for LP := 2 * AN - 2 downto AN do
+ begin
+ if ((LZz[LP shr 6] shr (LP and 63)) and 1) = 0 then
+ Continue;
+ LQ0 := LP - AN;
+ LQ1 := LP - AN + AK;
+ LZz[LQ0 shr 6] := LZz[LQ0 shr 6] xor (UInt64(1) shl (LQ0 and 63));
+ LZz[LQ1 shr 6] := LZz[LQ1 shr 6] xor (UInt64(1) shl (LQ1 and 63));
+ end;
+ System.SetLength(Result, LSize);
+ TNat.Copy64(LSize, LZz, 0, Result, 0);
+ LPartial := AN and 63;
+ if LPartial = 0 then
+ LPartialMask := High(UInt64)
+ else
+ LPartialMask := (UInt64(1) shl LPartial) - 1;
+ Result[LSize - 1] := Result[LSize - 1] and LPartialMask;
+end;
+
+function TTestBinPoly.ReferencePentanomialMul(AN, AK1, AK2, AK3: Int32;
+ const AX, AY: TCryptoLibUInt64Array): TCryptoLibUInt64Array;
+var
+ LSize, LP, LQ0, LQ1, LQ2, LQ3, LPartial: Int32;
+ LPartialMask: UInt64;
+ LZz: TCryptoLibUInt64Array;
+begin
+ LSize := (AN + 63) shr 6;
+ LZz := CarrylessMul(AN, AX, AY);
+ for LP := 2 * AN - 2 downto AN do
+ begin
+ if ((LZz[LP shr 6] shr (LP and 63)) and 1) = 0 then
+ Continue;
+ LQ0 := LP - AN;
+ LQ1 := LP - AN + AK1;
+ LQ2 := LP - AN + AK2;
+ LQ3 := LP - AN + AK3;
+ LZz[LQ0 shr 6] := LZz[LQ0 shr 6] xor (UInt64(1) shl (LQ0 and 63));
+ LZz[LQ1 shr 6] := LZz[LQ1 shr 6] xor (UInt64(1) shl (LQ1 and 63));
+ LZz[LQ2 shr 6] := LZz[LQ2 shr 6] xor (UInt64(1) shl (LQ2 and 63));
+ LZz[LQ3 shr 6] := LZz[LQ3 shr 6] xor (UInt64(1) shl (LQ3 and 63));
+ end;
+ System.SetLength(Result, LSize);
+ TNat.Copy64(LSize, LZz, 0, Result, 0);
+ LPartial := AN and 63;
+ if LPartial = 0 then
+ LPartialMask := High(UInt64)
+ else
+ LPartialMask := (UInt64(1) shl LPartial) - 1;
+ Result[LSize - 1] := Result[LSize - 1] and LPartialMask;
+end;
+
+procedure TTestBinPoly.RunAllOpsAtOffsets(const AMul: IBinPolyMul; AN: Int32;
+ const ARandom: IRandom; const ALabel: string);
+var
+ LSize: Int32;
+ LX, LY, LZRef, LXBuf, LYBuf, LZBuf, LXBufBefore, LYBufBefore, LZBufBefore: TCryptoLibUInt64Array;
+ LZInit: TCryptoLibUInt64Array;
+ LSn: Int32;
+begin
+ LSize := AMul.Size;
+
+ LX := RandomReduced(ARandom, AN);
+ LY := RandomReduced(ARandom, AN);
+ LZRef := TBinPolys.Create(LSize);
+ AMul.Multiply(LX, 0, LY, 0, LZRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LYBuf := PadBuffer(LSize, OffY, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ TNat.Copy64(LSize, LY, 0, LYBuf, OffY);
+ LXBufBefore := System.Copy(LXBuf);
+ LYBufBefore := System.Copy(LYBuf);
+ LZBufBefore := System.Copy(LZBuf);
+ AMul.Multiply(LXBuf, OffX, LYBuf, OffY, LZBuf, OffZ);
+ AssertSliceEquals(LZRef, LZBuf, OffZ, LSize, ALabel + ' Multiply');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBufBefore, LXBuf, ALabel + ' Multiply xBuf clobbered');
+ AssertUInt64ArraysEqual(System.Length(LYBuf), LYBufBefore, LYBuf, ALabel + ' Multiply yBuf clobbered');
+ AssertGuardZonesEqual(LZBufBefore, LZBuf, OffZ, LSize, ALabel + ' Multiply zBuf');
+
+ LX := RandomReduced(ARandom, AN);
+ LZRef := TBinPolys.Create(LSize);
+ AMul.Square(LX, 0, LZRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ LXBufBefore := System.Copy(LXBuf);
+ LZBufBefore := System.Copy(LZBuf);
+ AMul.Square(LXBuf, OffX, LZBuf, OffZ);
+ AssertSliceEquals(LZRef, LZBuf, OffZ, LSize, ALabel + ' Square');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBufBefore, LXBuf, ALabel + ' Square xBuf clobbered');
+ AssertGuardZonesEqual(LZBufBefore, LZBuf, OffZ, LSize, ALabel + ' Square zBuf');
+
+ LSn := 7;
+ LX := RandomReduced(ARandom, AN);
+ LZRef := TBinPolys.Create(LSize);
+ AMul.SquareN(LX, 0, LSn, LZRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ LXBufBefore := System.Copy(LXBuf);
+ LZBufBefore := System.Copy(LZBuf);
+ AMul.SquareN(LXBuf, OffX, LSn, LZBuf, OffZ);
+ AssertSliceEquals(LZRef, LZBuf, OffZ, LSize, ALabel + ' SquareN');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBufBefore, LXBuf, ALabel + ' SquareN xBuf clobbered');
+ AssertGuardZonesEqual(LZBufBefore, LZBuf, OffZ, LSize, ALabel + ' SquareN zBuf');
+
+ LX := RandomReduced(ARandom, AN);
+ LY := RandomReduced(ARandom, AN);
+ LZRef := TBinPolys.Create(LSize);
+ TBinPolys.Add(LSize, LX, 0, LY, 0, LZRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LYBuf := PadBuffer(LSize, OffY, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ TNat.Copy64(LSize, LY, 0, LYBuf, OffY);
+ LXBufBefore := System.Copy(LXBuf);
+ LYBufBefore := System.Copy(LYBuf);
+ LZBufBefore := System.Copy(LZBuf);
+ TBinPolys.Add(LSize, LXBuf, OffX, LYBuf, OffY, LZBuf, OffZ);
+ AssertSliceEquals(LZRef, LZBuf, OffZ, LSize, ALabel + ' Add');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBufBefore, LXBuf, ALabel + ' Add xBuf clobbered');
+ AssertUInt64ArraysEqual(System.Length(LYBuf), LYBufBefore, LYBuf, ALabel + ' Add yBuf clobbered');
+ AssertGuardZonesEqual(LZBufBefore, LZBuf, OffZ, LSize, ALabel + ' Add zBuf');
+
+ LX := RandomReduced(ARandom, AN);
+ LZInit := RandomReduced(ARandom, AN);
+ LZRef := System.Copy(LZInit);
+ TBinPolys.AddTo(LSize, LX, 0, LZRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ TNat.Copy64(LSize, LZInit, 0, LZBuf, OffZ);
+ LXBufBefore := System.Copy(LXBuf);
+ LZBufBefore := System.Copy(LZBuf);
+ TBinPolys.AddTo(LSize, LXBuf, OffX, LZBuf, OffZ);
+ AssertSliceEquals(LZRef, LZBuf, OffZ, LSize, ALabel + ' AddTo');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBufBefore, LXBuf, ALabel + ' AddTo xBuf clobbered');
+ AssertGuardZonesEqual(LZBufBefore, LZBuf, OffZ, LSize, ALabel + ' AddTo zBuf');
+end;
+
+procedure TTestBinPoly.RunInvertChecks(const AMul: IBinPolyMul; const AInv: IBinPolyInv;
+ AN: Int32; const ARandom: IRandom; const ALabel: string);
+var
+ LSize, LT: Int32;
+ LOne, LZero, LZInv, LA, LAInv, LProd, LAInvInv, LB, LExpected: TCryptoLibUInt64Array;
+begin
+ LSize := AMul.Size;
+ LOne := TBinPolys.Create(LSize);
+ LOne[0] := 1;
+ LZero := TBinPolys.Create(LSize);
+ LZInv := TBinPolys.Create(LSize);
+ AInv.Invert(LZero, 0, LZInv, 0);
+ AssertUInt64ArraysEqual(LSize, LZero, LZInv, ALabel + ' Invert(0)');
+ AInv.Invert(LOne, 0, LZInv, 0);
+ AssertUInt64ArraysEqual(LSize, LOne, LZInv, ALabel + ' Invert(1)');
+
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LA := RandomReduced(ARandom, AN);
+ if TBinPolys.EqualTo(LSize, LA, 0, LZero, 0) <> 0 then
+ Continue;
+ LAInv := TBinPolys.Create(LSize);
+ AInv.Invert(LA, 0, LAInv, 0);
+ LProd := TBinPolys.Create(LSize);
+ AMul.Multiply(LA, 0, LAInv, 0, LProd, 0);
+ AssertUInt64ArraysEqual(LSize, LOne, LProd, ALabel + ' a * inv(a) trial ' + IntToStr(LT));
+ LAInvInv := TBinPolys.Create(LSize);
+ AInv.Invert(LAInv, 0, LAInvInv, 0);
+ AssertUInt64ArraysEqual(LSize, LA, LAInvInv, ALabel + ' inv(inv(a)) trial ' + IntToStr(LT));
+ end;
+
+ LB := RandomReduced(ARandom, AN);
+ if TBinPolys.EqualTo(LSize, LB, 0, LZero, 0) = 0 then
+ begin
+ LExpected := TBinPolys.Create(LSize);
+ AInv.Invert(LB, 0, LExpected, 0);
+ AInv.Invert(LB, 0, LB, 0);
+ AssertUInt64ArraysEqual(LSize, LExpected, LB, ALabel + ' in-place invert');
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_Add_AgainstXor_BikeR1;
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LT, LI: Int32;
+ LX, LY, LZ: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LRandom := TRandom.Create(FixedSeed);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, BikeR1);
+ LY := RandomReduced(LRandom, BikeR1);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ TBinPolys.Add(LBinomial.Size, LX, 0, LY, 0, LZ, 0);
+ for LI := 0 to LBinomial.Size - 1 do
+ CheckEquals(LX[LI] xor LY[LI], LZ[LI], 'Add at limb ' + IntToStr(LI));
+ end;
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_AddTo_AgainstXor_BikeR1;
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LT, LI: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LRandom := TRandom.Create(FixedSeed + 1);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, BikeR1);
+ LZ := RandomReduced(LRandom, BikeR1);
+ LExpected := System.Copy(LZ);
+ for LI := 0 to LBinomial.Size - 1 do
+ LExpected[LI] := LX[LI] xor LZ[LI];
+ TBinPolys.AddTo(LBinomial.Size, LX, 0, LZ, 0);
+ AssertUInt64ArraysEqual(LBinomial.Size, LExpected, LZ, 'trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_Multiply_AgainstReference_BikeR1;
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LT: Int32;
+ LX, LY, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LRandom := TRandom.Create(FixedSeed + 2);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, BikeR1);
+ LY := RandomReduced(LRandom, BikeR1);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ LBinomial.Multiply(LX, 0, LY, 0, LZ, 0);
+ LExpected := ReferenceBinomialMul(BikeR1, LX, LY);
+ AssertUInt64ArraysEqual(LBinomial.Size, LExpected, LZ, 'trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_Multiply_AgainstReference_Small;
+const
+ SmallBinomials: array [0 .. 17] of TBinCase = (
+ (CaseName: 'evenBin_n_66'; N: 66),
+ (CaseName: 'evenBin_n_96'; N: 96),
+ (CaseName: 'evenBin_n130'; N: 130),
+ (CaseName: 'evenBin_n160'; N: 160),
+ (CaseName: 'evenBin_n_64'; N: 64),
+ (CaseName: 'evenBin_n128'; N: 128),
+ (CaseName: 'evenBin_n256'; N: 256),
+ (CaseName: 'evenBin_n512'; N: 512),
+ (CaseName: 'small_n_63'; N: 63),
+ (CaseName: 'small_n127'; N: 127),
+ (CaseName: 'small_n191'; N: 191),
+ (CaseName: 'small_n255'; N: 255),
+ (CaseName: 'small_n319'; N: 319),
+ (CaseName: 'small_n383'; N: 383),
+ (CaseName: 'small_n447'; N: 447),
+ (CaseName: 'small_n511'; N: 511),
+ (CaseName: 'small_n575'; N: 575),
+ (CaseName: 'small_n639'; N: 639));
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LT: Int32;
+ LX, LY, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(SmallBinomials) to High(SmallBinomials) do
+ begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(SmallBinomials[LC].N);
+ LRandom := TRandom.Create(FixedSeed + SmallBinomials[LC].N);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, SmallBinomials[LC].N);
+ LY := RandomReduced(LRandom, SmallBinomials[LC].N);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ LBinomial.Multiply(LX, 0, LY, 0, LZ, 0);
+ LExpected := ReferenceBinomialMul(SmallBinomials[LC].N, LX, LY);
+ AssertUInt64ArraysEqual(LBinomial.Size, LExpected, LZ,
+ SmallBinomials[LC].CaseName + ' trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_Square_AgainstReference_Even;
+const
+ EvenBinomials: array [0 .. 7] of TBinCase = (
+ (CaseName: 'evenBin_n_66'; N: 66),
+ (CaseName: 'evenBin_n_96'; N: 96),
+ (CaseName: 'evenBin_n130'; N: 130),
+ (CaseName: 'evenBin_n160'; N: 160),
+ (CaseName: 'evenBin_n_64'; N: 64),
+ (CaseName: 'evenBin_n128'; N: 128),
+ (CaseName: 'evenBin_n256'; N: 256),
+ (CaseName: 'evenBin_n512'; N: 512));
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LT: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(EvenBinomials) to High(EvenBinomials) do
+ begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(EvenBinomials[LC].N);
+ LRandom := TRandom.Create(FixedSeed + EvenBinomials[LC].N);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, EvenBinomials[LC].N);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ LBinomial.Square(LX, 0, LZ, 0);
+ LExpected := ReferenceBinomialMul(EvenBinomials[LC].N, LX, LX);
+ AssertUInt64ArraysEqual(LBinomial.Size, LExpected, LZ,
+ EvenBinomials[LC].CaseName + ' trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_Multiply_MultiplyByZero_BikeR1;
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LX, LZero, LZ: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LRandom := TRandom.Create(FixedSeed + 3);
+ try
+ LX := RandomReduced(LRandom, BikeR1);
+ LZero := TBinPolys.Create(LBinomial.Size);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ LBinomial.Multiply(LX, 0, LZero, 0, LZ, 0);
+ AssertUInt64ArraysEqual(LBinomial.Size, LZero, LZ, 'multiply by zero');
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_Multiply_MultiplyByOne_BikeR1;
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LX, LOne, LZ: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LRandom := TRandom.Create(FixedSeed + 4);
+ try
+ LX := RandomReduced(LRandom, BikeR1);
+ LOne := TBinPolys.Create(LBinomial.Size);
+ LOne[0] := 1;
+ LZ := TBinPolys.Create(LBinomial.Size);
+ LBinomial.Multiply(LX, 0, LOne, 0, LZ, 0);
+ AssertUInt64ArraysEqual(LBinomial.Size, LX, LZ, 'multiply by one');
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_Square_AgainstReferenceMultiplyBySelf_BikeR1;
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LT: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LRandom := TRandom.Create(FixedSeed + 5);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, BikeR1);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ LBinomial.Square(LX, 0, LZ, 0);
+ LExpected := ReferenceBinomialMul(BikeR1, LX, LX);
+ AssertUInt64ArraysEqual(LBinomial.Size, LExpected, LZ, 'trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_SquareN_AgainstRepeatedSquare_BikeR1;
+const
+ SquareNs: array [0 .. 4] of Int32 = (1, 2, 3, 7, 16);
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LI, LN: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LRandom := TRandom.Create(FixedSeed + 6);
+ try
+ for LN := Low(SquareNs) to High(SquareNs) do
+ begin
+ LX := RandomReduced(LRandom, BikeR1);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ LBinomial.SquareN(LX, 0, SquareNs[LN], LZ, 0);
+ LExpected := TBinPolys.Create(LBinomial.Size);
+ LBinomial.Square(LX, 0, LExpected, 0);
+ for LI := 1 to SquareNs[LN] - 1 do
+ LBinomial.Square(LExpected, 0, LExpected, 0);
+ AssertUInt64ArraysEqual(LBinomial.Size, LExpected, LZ, 'n = ' + IntToStr(SquareNs[LN]));
+ end;
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_SquareN_ZeroNThrows_BikeR1;
+var
+ LBinomial: IBinPolyMul;
+ LX, LZ: TCryptoLibUInt64Array;
+begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BikeR1);
+ LX := TBinPolys.Create(LBinomial.Size);
+ LZ := TBinPolys.Create(LBinomial.Size);
+ try
+ LBinomial.SquareN(LX, 0, 0, LZ, 0);
+ Fail('expected exception: SquareN n=0');
+ except
+ on E: Exception do
+ Check(True, 'SquareN n=0');
+ end;
+ try
+ LBinomial.SquareN(LX, 0, -1, LZ, 0);
+ Fail('expected exception: SquareN n=-1');
+ except
+ on E: Exception do
+ Check(True, 'SquareN n=-1');
+ end;
+end;
+
+procedure TTestBinPoly.TestBinomial_AllOps_NonZeroOffsets;
+const
+ BinomialOffsetCases: array [0 .. 38] of TBinCase = (
+ (CaseName: 'evenBin_n_66'; N: 66),
+ (CaseName: 'evenBin_n_96'; N: 96),
+ (CaseName: 'evenBin_n130'; N: 130),
+ (CaseName: 'evenBin_n160'; N: 160),
+ (CaseName: 'evenBin_n_64'; N: 64),
+ (CaseName: 'evenBin_n128'; N: 128),
+ (CaseName: 'evenBin_n256'; N: 256),
+ (CaseName: 'evenBin_n512'; N: 512),
+ (CaseName: 'med_n_703'; N: 703),
+ (CaseName: 'med_n_767'; N: 767),
+ (CaseName: 'med_n_831'; N: 831),
+ (CaseName: 'med_n_895'; N: 895),
+ (CaseName: 'med_n_959'; N: 959),
+ (CaseName: 'med_n1023'; N: 1023),
+ (CaseName: 'med_n1087'; N: 1087),
+ (CaseName: 'med_n1151'; N: 1151),
+ (CaseName: 'med_n1215'; N: 1215),
+ (CaseName: 'med_n1279'; N: 1279),
+ (CaseName: 'med_n1343'; N: 1343),
+ (CaseName: 'med_n1407'; N: 1407),
+ (CaseName: 'med_n1471'; N: 1471),
+ (CaseName: 'med_n1535'; N: 1535),
+ (CaseName: 'med_n1599'; N: 1599),
+ (CaseName: 'med_n1663'; N: 1663),
+ (CaseName: 'med_n1727'; N: 1727),
+ (CaseName: 'med_n1791'; N: 1791),
+ (CaseName: 'med_n1855'; N: 1855),
+ (CaseName: 'med_n1919'; N: 1919),
+ (CaseName: 'med_n1983'; N: 1983),
+ (CaseName: 'small_n_63'; N: 63),
+ (CaseName: 'small_n127'; N: 127),
+ (CaseName: 'small_n191'; N: 191),
+ (CaseName: 'small_n255'; N: 255),
+ (CaseName: 'small_n319'; N: 319),
+ (CaseName: 'small_n383'; N: 383),
+ (CaseName: 'small_n447'; N: 447),
+ (CaseName: 'small_n511'; N: 511),
+ (CaseName: 'small_n575'; N: 575),
+ (CaseName: 'small_n639'; N: 639));
+var
+ LBinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC: Int32;
+begin
+ for LC := Low(BinomialOffsetCases) to High(BinomialOffsetCases) do
+ begin
+ LBinomial := TBinPolys.TBinPolysMul.Binomial(BinomialOffsetCases[LC].N);
+ LRandom := TRandom.Create(FixedSeed + 1100 + BinomialOffsetCases[LC].N);
+ try
+ RunAllOpsAtOffsets(LBinomial, BinomialOffsetCases[LC].N, LRandom,
+ BinomialOffsetCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestTrinomial_Multiply_AgainstReference;
+var
+ LTrinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LT: Int32;
+ LX, LY, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(TrinomialCases) to High(TrinomialCases) do
+ begin
+ LTrinomial := TBinPolys.TBinPolysMul.Trinomial(TrinomialCases[LC].N, TrinomialCases[LC].K);
+ LRandom := TRandom.Create(FixedSeed + 100 + TrinomialCases[LC].N);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, TrinomialCases[LC].N);
+ LY := RandomReduced(LRandom, TrinomialCases[LC].N);
+ LZ := TBinPolys.Create(LTrinomial.Size);
+ LTrinomial.Multiply(LX, 0, LY, 0, LZ, 0);
+ LExpected := ReferenceTrinomialMul(TrinomialCases[LC].N, TrinomialCases[LC].K, LX, LY);
+ AssertUInt64ArraysEqual(LTrinomial.Size, LExpected, LZ,
+ TrinomialCases[LC].CaseName + ' trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestTrinomial_Multiply_MultiplyByZero;
+var
+ LTrinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC: Int32;
+ LX, LZero, LZ: TCryptoLibUInt64Array;
+begin
+ for LC := Low(TrinomialCases) to High(TrinomialCases) do
+ begin
+ LTrinomial := TBinPolys.TBinPolysMul.Trinomial(TrinomialCases[LC].N, TrinomialCases[LC].K);
+ LRandom := TRandom.Create(FixedSeed + 200 + TrinomialCases[LC].N);
+ try
+ LX := RandomReduced(LRandom, TrinomialCases[LC].N);
+ LZero := TBinPolys.Create(LTrinomial.Size);
+ LZ := TBinPolys.Create(LTrinomial.Size);
+ LTrinomial.Multiply(LX, 0, LZero, 0, LZ, 0);
+ AssertUInt64ArraysEqual(LTrinomial.Size, LZero, LZ, TrinomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestTrinomial_Multiply_MultiplyByOne;
+var
+ LTrinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC: Int32;
+ LX, LOne, LZ: TCryptoLibUInt64Array;
+begin
+ for LC := Low(TrinomialCases) to High(TrinomialCases) do
+ begin
+ LTrinomial := TBinPolys.TBinPolysMul.Trinomial(TrinomialCases[LC].N, TrinomialCases[LC].K);
+ LRandom := TRandom.Create(FixedSeed + 300 + TrinomialCases[LC].N);
+ try
+ LX := RandomReduced(LRandom, TrinomialCases[LC].N);
+ LOne := TBinPolys.Create(LTrinomial.Size);
+ LOne[0] := 1;
+ LZ := TBinPolys.Create(LTrinomial.Size);
+ LTrinomial.Multiply(LX, 0, LOne, 0, LZ, 0);
+ AssertUInt64ArraysEqual(LTrinomial.Size, LX, LZ, TrinomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestTrinomial_Square_AgainstReferenceMultiplyBySelf;
+var
+ LTrinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LT: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(TrinomialCases) to High(TrinomialCases) do
+ begin
+ LTrinomial := TBinPolys.TBinPolysMul.Trinomial(TrinomialCases[LC].N, TrinomialCases[LC].K);
+ LRandom := TRandom.Create(FixedSeed + 400 + TrinomialCases[LC].N);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, TrinomialCases[LC].N);
+ LZ := TBinPolys.Create(LTrinomial.Size);
+ LTrinomial.Square(LX, 0, LZ, 0);
+ LExpected := ReferenceTrinomialMul(TrinomialCases[LC].N, TrinomialCases[LC].K, LX, LX);
+ AssertUInt64ArraysEqual(LTrinomial.Size, LExpected, LZ,
+ TrinomialCases[LC].CaseName + ' trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestTrinomial_SquareN_AgainstRepeatedSquare;
+const
+ SquareNs: array [0 .. 4] of Int32 = (1, 2, 3, 7, 16);
+var
+ LTrinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LI, LSn: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(TrinomialCases) to High(TrinomialCases) do
+ begin
+ LTrinomial := TBinPolys.TBinPolysMul.Trinomial(TrinomialCases[LC].N, TrinomialCases[LC].K);
+ LRandom := TRandom.Create(FixedSeed + 500 + TrinomialCases[LC].N);
+ try
+ for LSn := Low(SquareNs) to High(SquareNs) do
+ begin
+ LX := RandomReduced(LRandom, TrinomialCases[LC].N);
+ LZ := TBinPolys.Create(LTrinomial.Size);
+ LTrinomial.SquareN(LX, 0, SquareNs[LSn], LZ, 0);
+ LExpected := TBinPolys.Create(LTrinomial.Size);
+ LTrinomial.Square(LX, 0, LExpected, 0);
+ for LI := 1 to SquareNs[LSn] - 1 do
+ LTrinomial.Square(LExpected, 0, LExpected, 0);
+ AssertUInt64ArraysEqual(LTrinomial.Size, LExpected, LZ,
+ TrinomialCases[LC].CaseName + ' sn = ' + IntToStr(SquareNs[LSn]));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestTrinomial_AllOps_NonZeroOffsets;
+var
+ LTrinomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC: Int32;
+begin
+ for LC := Low(TrinomialCases) to High(TrinomialCases) do
+ begin
+ LTrinomial := TBinPolys.TBinPolysMul.Trinomial(TrinomialCases[LC].N, TrinomialCases[LC].K);
+ LRandom := TRandom.Create(FixedSeed + 1200 + TrinomialCases[LC].N);
+ try
+ RunAllOpsAtOffsets(LTrinomial, TrinomialCases[LC].N, LRandom, TrinomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestPentanomial_Multiply_AgainstReference;
+var
+ LPentanomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LT: Int32;
+ LX, LY, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(PentanomialCases) to High(PentanomialCases) do
+ begin
+ LPentanomial := TBinPolys.TBinPolysMul.Pentanomial(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3);
+ LRandom := TRandom.Create(FixedSeed + 600 + PentanomialCases[LC].N);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, PentanomialCases[LC].N);
+ LY := RandomReduced(LRandom, PentanomialCases[LC].N);
+ LZ := TBinPolys.Create(LPentanomial.Size);
+ LPentanomial.Multiply(LX, 0, LY, 0, LZ, 0);
+ LExpected := ReferencePentanomialMul(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3, LX, LY);
+ AssertUInt64ArraysEqual(LPentanomial.Size, LExpected, LZ,
+ PentanomialCases[LC].CaseName + ' trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestPentanomial_Multiply_MultiplyByZero;
+var
+ LPentanomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC: Int32;
+ LX, LZero, LZ: TCryptoLibUInt64Array;
+begin
+ for LC := Low(PentanomialCases) to High(PentanomialCases) do
+ begin
+ LPentanomial := TBinPolys.TBinPolysMul.Pentanomial(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3);
+ LRandom := TRandom.Create(FixedSeed + 700 + PentanomialCases[LC].N);
+ try
+ LX := RandomReduced(LRandom, PentanomialCases[LC].N);
+ LZero := TBinPolys.Create(LPentanomial.Size);
+ LZ := TBinPolys.Create(LPentanomial.Size);
+ LPentanomial.Multiply(LX, 0, LZero, 0, LZ, 0);
+ AssertUInt64ArraysEqual(LPentanomial.Size, LZero, LZ, PentanomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestPentanomial_Multiply_MultiplyByOne;
+var
+ LPentanomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC: Int32;
+ LX, LOne, LZ: TCryptoLibUInt64Array;
+begin
+ for LC := Low(PentanomialCases) to High(PentanomialCases) do
+ begin
+ LPentanomial := TBinPolys.TBinPolysMul.Pentanomial(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3);
+ LRandom := TRandom.Create(FixedSeed + 800 + PentanomialCases[LC].N);
+ try
+ LX := RandomReduced(LRandom, PentanomialCases[LC].N);
+ LOne := TBinPolys.Create(LPentanomial.Size);
+ LOne[0] := 1;
+ LZ := TBinPolys.Create(LPentanomial.Size);
+ LPentanomial.Multiply(LX, 0, LOne, 0, LZ, 0);
+ AssertUInt64ArraysEqual(LPentanomial.Size, LX, LZ, PentanomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestPentanomial_Square_AgainstReferenceMultiplyBySelf;
+var
+ LPentanomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LT: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(PentanomialCases) to High(PentanomialCases) do
+ begin
+ LPentanomial := TBinPolys.TBinPolysMul.Pentanomial(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3);
+ LRandom := TRandom.Create(FixedSeed + 900 + PentanomialCases[LC].N);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ begin
+ LX := RandomReduced(LRandom, PentanomialCases[LC].N);
+ LZ := TBinPolys.Create(LPentanomial.Size);
+ LPentanomial.Square(LX, 0, LZ, 0);
+ LExpected := ReferencePentanomialMul(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3, LX, LX);
+ AssertUInt64ArraysEqual(LPentanomial.Size, LExpected, LZ,
+ PentanomialCases[LC].CaseName + ' trial ' + IntToStr(LT));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestPentanomial_SquareN_AgainstRepeatedSquare;
+const
+ SquareNs: array [0 .. 4] of Int32 = (1, 2, 3, 7, 16);
+var
+ LPentanomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC, LI, LSn: Int32;
+ LX, LZ, LExpected: TCryptoLibUInt64Array;
+begin
+ for LC := Low(PentanomialCases) to High(PentanomialCases) do
+ begin
+ LPentanomial := TBinPolys.TBinPolysMul.Pentanomial(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3);
+ LRandom := TRandom.Create(FixedSeed + 1000 + PentanomialCases[LC].N);
+ try
+ for LSn := Low(SquareNs) to High(SquareNs) do
+ begin
+ LX := RandomReduced(LRandom, PentanomialCases[LC].N);
+ LZ := TBinPolys.Create(LPentanomial.Size);
+ LPentanomial.SquareN(LX, 0, SquareNs[LSn], LZ, 0);
+ LExpected := TBinPolys.Create(LPentanomial.Size);
+ LPentanomial.Square(LX, 0, LExpected, 0);
+ for LI := 1 to SquareNs[LSn] - 1 do
+ LPentanomial.Square(LExpected, 0, LExpected, 0);
+ AssertUInt64ArraysEqual(LPentanomial.Size, LExpected, LZ,
+ PentanomialCases[LC].CaseName + ' sn = ' + IntToStr(SquareNs[LSn]));
+ end;
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestPentanomial_AllOps_NonZeroOffsets;
+var
+ LPentanomial: IBinPolyMul;
+ LRandom: IRandom;
+ LC: Int32;
+begin
+ for LC := Low(PentanomialCases) to High(PentanomialCases) do
+ begin
+ LPentanomial := TBinPolys.TBinPolysMul.Pentanomial(PentanomialCases[LC].N, PentanomialCases[LC].K1,
+ PentanomialCases[LC].K2, PentanomialCases[LC].K3);
+ LRandom := TRandom.Create(FixedSeed + 1300 + PentanomialCases[LC].N);
+ try
+ RunAllOpsAtOffsets(LPentanomial, PentanomialCases[LC].N, LRandom, PentanomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestFactory_RejectsInvalidParameters;
+begin
+ try
+ TBinPolys.TBinPolysMul.Binomial(0);
+ Fail('expected exception: Binomial(0)');
+ except
+ on E: Exception do
+ Check(True, 'Binomial(0)');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Binomial(-1);
+ Fail('expected exception: Binomial(-1)');
+ except
+ on E: Exception do
+ Check(True, 'Binomial(-1)');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Trinomial(BikeR1, 0);
+ Fail('expected exception: Trinomial k=0');
+ except
+ on E: Exception do
+ Check(True, 'Trinomial k=0');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Trinomial(BikeR1, BikeR1);
+ Fail('expected exception: Trinomial k=n');
+ except
+ on E: Exception do
+ Check(True, 'Trinomial k=n');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Trinomial(2, 1);
+ Fail('expected exception: Trinomial n<3');
+ except
+ on E: Exception do
+ Check(True, 'Trinomial n<3');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Pentanomial(BikeR1, 5, 5, 9);
+ Fail('expected exception: Pentanomial k2 not > k1');
+ except
+ on E: Exception do
+ Check(True, 'Pentanomial k2 not > k1');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Pentanomial(BikeR1, 1, 5, 5);
+ Fail('expected exception: Pentanomial k3 not > k2');
+ except
+ on E: Exception do
+ Check(True, 'Pentanomial k3 not > k2');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Pentanomial(BikeR1, 1, 3, BikeR1);
+ Fail('expected exception: Pentanomial k3 not < n');
+ except
+ on E: Exception do
+ Check(True, 'Pentanomial k3 not < n');
+ end;
+ try
+ TBinPolys.TBinPolysMul.Pentanomial(4, 1, 2, 3);
+ Fail('expected exception: Pentanomial n<5');
+ except
+ on E: Exception do
+ Check(True, 'Pentanomial n<5');
+ end;
+end;
+
+procedure TTestBinPoly.TestFactory_AcceptsEvenN;
+var
+ LMul: IBinPolyMul;
+begin
+ LMul := TBinPolys.TBinPolysMul.Binomial(2);
+ Check(LMul <> nil, 'Binomial(2)');
+ LMul := TBinPolys.TBinPolysMul.Binomial(64);
+ Check(LMul <> nil, 'Binomial(64)');
+ LMul := TBinPolys.TBinPolysMul.Trinomial(4, 1);
+ Check(LMul <> nil, 'Trinomial(4,1)');
+ LMul := TBinPolys.TBinPolysMul.Trinomial(64, 1);
+ Check(LMul <> nil, 'Trinomial(64,1)');
+ LMul := TBinPolys.TBinPolysMul.Trinomial(128, 7);
+ Check(LMul <> nil, 'Trinomial(128,7)');
+ LMul := TBinPolys.TBinPolysMul.Pentanomial(6, 1, 2, 3);
+ Check(LMul <> nil, 'Pentanomial(6,1,2,3)');
+ LMul := TBinPolys.TBinPolysMul.Pentanomial(64, 1, 2, 3);
+ Check(LMul <> nil, 'Pentanomial(64,1,2,3)');
+ LMul := TBinPolys.TBinPolysMul.Pentanomial(128, 2, 5, 7);
+ Check(LMul <> nil, 'Pentanomial(128,2,5,7)');
+end;
+
+procedure TTestBinPoly.TestTrinomial_Invert_RoundTrip;
+var
+ LMul: IBinPolyMul;
+ LInv: IBinPolyInv;
+ LRandom: IRandom;
+ LC: Int32;
+begin
+ for LC := Low(SectTrinomialCases) to High(SectTrinomialCases) do
+ begin
+ LMul := TBinPolys.TBinPolysMul.Trinomial(SectTrinomialCases[LC].N, SectTrinomialCases[LC].K);
+ LInv := TBinPolys.TBinPolysInv.ItohTsujii(LMul);
+ LRandom := TRandom.Create(FixedSeed + 1400 + SectTrinomialCases[LC].N);
+ try
+ RunInvertChecks(LMul, LInv, SectTrinomialCases[LC].N, LRandom, SectTrinomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestPentanomial_Invert_RoundTrip;
+var
+ LMul: IBinPolyMul;
+ LInv: IBinPolyInv;
+ LRandom: IRandom;
+ LC: Int32;
+begin
+ for LC := Low(SectPentanomialCases) to High(SectPentanomialCases) do
+ begin
+ LMul := TBinPolys.TBinPolysMul.Pentanomial(SectPentanomialCases[LC].N, SectPentanomialCases[LC].K1,
+ SectPentanomialCases[LC].K2, SectPentanomialCases[LC].K3);
+ LInv := TBinPolys.TBinPolysInv.ItohTsujii(LMul);
+ LRandom := TRandom.Create(FixedSeed + 1500 + SectPentanomialCases[LC].N);
+ try
+ RunInvertChecks(LMul, LInv, SectPentanomialCases[LC].N, LRandom, SectPentanomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+
+ for LC := Low(X962EvenPentanomialCases) to High(X962EvenPentanomialCases) do
+ begin
+ LMul := TBinPolys.TBinPolysMul.Pentanomial(X962EvenPentanomialCases[LC].N,
+ X962EvenPentanomialCases[LC].K1, X962EvenPentanomialCases[LC].K2, X962EvenPentanomialCases[LC].K3);
+ LInv := TBinPolys.TBinPolysInv.ItohTsujii(LMul);
+ LRandom := TRandom.Create(FixedSeed + 1500 + X962EvenPentanomialCases[LC].N);
+ try
+ RunInvertChecks(LMul, LInv, X962EvenPentanomialCases[LC].N, LRandom,
+ X962EvenPentanomialCases[LC].CaseName);
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestInv_Factory_RejectsNullAndDegenerate;
+begin
+ try
+ TBinPolys.TBinPolysInv.ItohTsujii(nil);
+ Fail('expected exception: ItohTsujii(null)');
+ except
+ on E: Exception do
+ Check(True, 'ItohTsujii(null)');
+ end;
+ try
+ TBinPolys.TBinPolysInv.ItohTsujii(TBinPolys.TBinPolysMul.Binomial(1));
+ Fail('expected exception: ItohTsujii(Binomial(1))');
+ except
+ on E: Exception do
+ Check(True, 'ItohTsujii(Binomial(1))');
+ end;
+end;
+
+// Cross-backend check: the x86/V128 backend must agree with the scalar backend
+// for Multiply, Square and SquareN, even when operands and outputs live at
+// non-zero offsets inside guard-padded buffers (verifies offset handling, that
+// inputs are never clobbered, and that nothing is written outside the result
+// slice).
+procedure TTestBinPoly.RunX86V128VsScalar(AN: Int32; const ARandom: IRandom;
+ const AContext: string);
+const
+ SquareNCount = 5;
+var
+ LReduce: IBinPolyReduce;
+ LScalar, LX86: IBinPolyMul;
+ LSize: Int32;
+ LX, LY, LRef, LXBuf, LYBuf, LZBuf, LXBefore, LYBefore, LZBefore: TCryptoLibUInt64Array;
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ LReduce := TBinPolyMulBaseBinomialReduce.Create(AN);
+ LScalar := TBinPolyScalarBackend.CreateBinPolyMul(AN, LReduce);
+ LX86 := TBinPolyX86V128Backend.CreateBinPolyMul(AN, LReduce);
+ LSize := LX86.Size;
+
+ // Multiply
+ LX := RandomReduced(ARandom, AN);
+ LY := RandomReduced(ARandom, AN);
+ LRef := TBinPolys.Create(LSize);
+ LScalar.Multiply(LX, 0, LY, 0, LRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LYBuf := PadBuffer(LSize, OffY, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ TNat.Copy64(LSize, LY, 0, LYBuf, OffY);
+ LXBefore := System.Copy(LXBuf);
+ LYBefore := System.Copy(LYBuf);
+ LZBefore := System.Copy(LZBuf);
+ LX86.Multiply(LXBuf, OffX, LYBuf, OffY, LZBuf, OffZ);
+ AssertSliceEquals(LRef, LZBuf, OffZ, LSize, AContext + ' Multiply');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBefore, LXBuf, AContext + ' Multiply xBuf clobbered');
+ AssertUInt64ArraysEqual(System.Length(LYBuf), LYBefore, LYBuf, AContext + ' Multiply yBuf clobbered');
+ AssertGuardZonesEqual(LZBefore, LZBuf, OffZ, LSize, AContext + ' Multiply zBuf');
+
+ // Square
+ LX := RandomReduced(ARandom, AN);
+ LRef := TBinPolys.Create(LSize);
+ LScalar.Square(LX, 0, LRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ LXBefore := System.Copy(LXBuf);
+ LZBefore := System.Copy(LZBuf);
+ LX86.Square(LXBuf, OffX, LZBuf, OffZ);
+ AssertSliceEquals(LRef, LZBuf, OffZ, LSize, AContext + ' Square');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBefore, LXBuf, AContext + ' Square xBuf clobbered');
+ AssertGuardZonesEqual(LZBefore, LZBuf, OffZ, LSize, AContext + ' Square zBuf');
+
+ // SquareN
+ LX := RandomReduced(ARandom, AN);
+ LRef := TBinPolys.Create(LSize);
+ LScalar.SquareN(LX, 0, SquareNCount, LRef, 0);
+ LXBuf := PadBuffer(LSize, OffX, OffPadTail, ARandom);
+ LZBuf := PadBuffer(LSize, OffZ, OffPadTail, ARandom);
+ TNat.Copy64(LSize, LX, 0, LXBuf, OffX);
+ LXBefore := System.Copy(LXBuf);
+ LZBefore := System.Copy(LZBuf);
+ LX86.SquareN(LXBuf, OffX, SquareNCount, LZBuf, OffZ);
+ AssertSliceEquals(LRef, LZBuf, OffZ, LSize, AContext + ' SquareN');
+ AssertUInt64ArraysEqual(System.Length(LXBuf), LXBefore, LXBuf, AContext + ' SquareN xBuf clobbered');
+ AssertGuardZonesEqual(LZBefore, LZBuf, OffZ, LSize, AContext + ' SquareN zBuf');
+end;
+
+procedure TTestBinPoly.AssertX86V128MultiplyEquals(AN: Int32;
+ const AX, AY: TCryptoLibUInt64Array; const AContext: string);
+var
+ LReduce: IBinPolyReduce;
+ LScalar, LX86: IBinPolyMul;
+ LScalarZ, LX86Z: TCryptoLibUInt64Array;
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ LReduce := TBinPolyMulBaseBinomialReduce.Create(AN);
+ LScalar := TBinPolyScalarBackend.CreateBinPolyMul(AN, LReduce);
+ LX86 := TBinPolyX86V128Backend.CreateBinPolyMul(AN, LReduce);
+ LScalarZ := TBinPolys.Create(LScalar.Size);
+ LX86Z := TBinPolys.Create(LX86.Size);
+ LScalar.Multiply(AX, 0, AY, 0, LScalarZ, 0);
+ LX86.Multiply(AX, 0, AY, 0, LX86Z, 0);
+ AssertUInt64ArraysEqual(LScalar.Size, LScalarZ, LX86Z, AContext);
+end;
+
+procedure TTestBinPoly.TestX86V128_Multiply_MatchesScalar;
+var
+ LRandom: IRandom;
+ LT: Int32;
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ LRandom := TRandom.Create(FixedSeed + 2000);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ RunX86V128VsScalar(BikeR1, LRandom,
+ 'BikeR1 equivalence trial ' + IntToStr(LT));
+ finally
+ LRandom := nil;
+ end;
+end;
+
+procedure TTestBinPoly.TestX86V128_SizeSweep;
+const
+ SweepCases: array [0 .. 17] of TBinCase = (
+ (CaseName: 'lsize1'; N: 32),
+ (CaseName: 'lsize2'; N: 96),
+ (CaseName: 'lsize3'; N: 160),
+ (CaseName: 'lsize4'; N: 224),
+ (CaseName: 'lsize5'; N: 288),
+ (CaseName: 'lsize6'; N: 352),
+ (CaseName: 'lsize7'; N: 416),
+ (CaseName: 'lsize8'; N: 480),
+ (CaseName: 'lsize9'; N: 544),
+ (CaseName: 'lsize10'; N: 608),
+ (CaseName: 'lsize11'; N: 672),
+ (CaseName: 'lsize12'; N: 736),
+ (CaseName: 'lsize17'; N: 1056),
+ (CaseName: 'lsize20'; N: 1248),
+ (CaseName: 'lsize31'; N: 1952),
+ (CaseName: 'lsize32'; N: 2016),
+ (CaseName: 'lsize48'; N: 3040),
+ (CaseName: 'lsize48b'; N: 3071));
+var
+ LRandom: IRandom;
+ LC, LT: Int32;
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ for LC := Low(SweepCases) to High(SweepCases) do
+ begin
+ LRandom := TRandom.Create(FixedSeed + SweepCases[LC].N);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ RunX86V128VsScalar(SweepCases[LC].N, LRandom,
+ SweepCases[LC].CaseName + ' trial ' + IntToStr(LT));
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+procedure TTestBinPoly.TestX86V128_LSize10_MidWindow;
+var
+ LRandom: IRandom;
+ LT: Int32;
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ LRandom := TRandom.Create(FixedSeed + 610);
+ try
+ for LT := 0 to RandomTrials * 2 - 1 do
+ RunX86V128VsScalar(610, LRandom,
+ 'LSize10 mid-window trial ' + IntToStr(LT));
+ finally
+ LRandom := nil;
+ end;
+end;
+
+// Exhaustively exercise every generated small fixed-size kernel (lsize 1..10)
+// through all three operations at non-zero offsets.
+procedure TTestBinPoly.TestX86V128_SmallSizes_AllOps;
+var
+ LRandom: IRandom;
+ LLSize, LT, LN: Int32;
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ for LLSize := 1 to 10 do
+ begin
+ LN := LLSize * 64;
+ LRandom := TRandom.Create(FixedSeed + 4000 + LLSize);
+ try
+ for LT := 0 to RandomTrials - 1 do
+ RunX86V128VsScalar(LN, LRandom,
+ 'small lsize' + IntToStr(LLSize) + ' trial ' + IntToStr(LT));
+ finally
+ LRandom := nil;
+ end;
+ end;
+end;
+
+// Multiplying by zero must yield zero and multiplying by one must be the
+// identity, matching the scalar backend, across small, medium and large sizes.
+procedure TTestBinPoly.TestX86V128_MultiplyByZeroAndOne;
+const
+ Sizes: array [0 .. 5] of Int32 = (64, 320, 608, 672, 1248, BikeR1);
+var
+ LRandom: IRandom;
+ LC, LSize: Int32;
+ LX, LZero, LOne: TCryptoLibUInt64Array;
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ LRandom := TRandom.Create(FixedSeed + 5000);
+ try
+ for LC := Low(Sizes) to High(Sizes) do
+ begin
+ LSize := (Sizes[LC] + 63) shr 6;
+ LX := RandomReduced(LRandom, Sizes[LC]);
+ LZero := TBinPolys.Create(LSize);
+ LOne := TBinPolys.Create(LSize);
+ LOne[0] := 1;
+ AssertX86V128MultiplyEquals(Sizes[LC], LX, LZero,
+ 'mul-by-zero n=' + IntToStr(Sizes[LC]));
+ AssertX86V128MultiplyEquals(Sizes[LC], LX, LOne,
+ 'mul-by-one n=' + IntToStr(Sizes[LC]));
+ end;
+ finally
+ LRandom := nil;
+ end;
+end;
+
+// Adversarial bit patterns (all-ones, single high bit, alternating) maximise
+// carryless lane interaction and catch lane-splice / shift errors that random
+// inputs may miss.
+procedure TTestBinPoly.TestX86V128_EdgeVectors;
+const
+ Sizes: array [0 .. 6] of Int32 = (64, 192, 608, 672, 736, 1248, BikeR1);
+var
+ LC, LSize, LTop, LBit: Int32;
+ LAllOnes, LAlt, LHighBit, LLowBit: TCryptoLibUInt64Array;
+
+ function MaskedTop(const AVec: TCryptoLibUInt64Array; AN: Int32)
+ : TCryptoLibUInt64Array;
+ var
+ LPartial: Int32;
+ begin
+ Result := AVec;
+ LPartial := AN and 63;
+ if LPartial <> 0 then
+ Result[System.Length(Result) - 1] := Result[System.Length(Result) - 1]
+ and ((UInt64(1) shl LPartial) - 1);
+ end;
+
+begin
+ if not TBinPolyX86V128Backend.IsEnabled then
+ Exit;
+
+ for LC := Low(Sizes) to High(Sizes) do
+ begin
+ LSize := (Sizes[LC] + 63) shr 6;
+
+ LAllOnes := TBinPolys.Create(LSize);
+ LAlt := TBinPolys.Create(LSize);
+ for LTop := 0 to LSize - 1 do
+ begin
+ LAllOnes[LTop] := UInt64($FFFFFFFFFFFFFFFF);
+ LAlt[LTop] := UInt64($AAAAAAAAAAAAAAAA);
+ end;
+ LAllOnes := MaskedTop(LAllOnes, Sizes[LC]);
+ LAlt := MaskedTop(LAlt, Sizes[LC]);
+
+ LHighBit := TBinPolys.Create(LSize);
+ LBit := Sizes[LC] - 1;
+ LHighBit[LBit shr 6] := UInt64(1) shl (LBit and 63);
+
+ LLowBit := TBinPolys.Create(LSize);
+ LLowBit[0] := 1;
+
+ AssertX86V128MultiplyEquals(Sizes[LC], LAllOnes, LAllOnes,
+ 'edge allones^2 n=' + IntToStr(Sizes[LC]));
+ AssertX86V128MultiplyEquals(Sizes[LC], LAllOnes, LAlt,
+ 'edge allones*alt n=' + IntToStr(Sizes[LC]));
+ AssertX86V128MultiplyEquals(Sizes[LC], LHighBit, LHighBit,
+ 'edge highbit^2 n=' + IntToStr(Sizes[LC]));
+ AssertX86V128MultiplyEquals(Sizes[LC], LHighBit, LAllOnes,
+ 'edge highbit*allones n=' + IntToStr(Sizes[LC]));
+ AssertX86V128MultiplyEquals(Sizes[LC], LAlt, LLowBit,
+ 'edge alt*lowbit n=' + IntToStr(Sizes[LC]));
+ end;
+end;
+
+procedure TTestBinPoly.TestBitLengthVar_AgainstReference;
+const
+ Sizes: array [0 .. 4] of Int32 = (1, 2, 3, 5, 9);
+var
+ LRandom: IRandom;
+ LS, LT: Int32;
+ LZero, LOne, LTop, LX: TCryptoLibUInt64Array;
+begin
+ LRandom := TRandom.Create(FixedSeed + 1600);
+ try
+ for LS := Low(Sizes) to High(Sizes) do
+ begin
+ System.SetLength(LZero, Sizes[LS]);
+ CheckEquals(0, TBinPolys.BitLengthVar(Sizes[LS], LZero, 0), 'zero size ' + IntToStr(Sizes[LS]));
+ System.SetLength(LOne, Sizes[LS]);
+ LOne[0] := 1;
+ CheckEquals(1, TBinPolys.BitLengthVar(Sizes[LS], LOne, 0), 'one size ' + IntToStr(Sizes[LS]));
+ System.SetLength(LTop, Sizes[LS]);
+ LTop[Sizes[LS] - 1] := UInt64(1) shl 63;
+ CheckEquals(Sizes[LS] * 64, TBinPolys.BitLengthVar(Sizes[LS], LTop, 0),
+ 'top size ' + IntToStr(Sizes[LS]));
+ for LT := 0 to 31 do
+ begin
+ LX := RandomLimbs(LRandom, Sizes[LS]);
+ CheckEquals(ReferenceBitLength(Sizes[LS], LX),
+ TBinPolys.BitLengthVar(Sizes[LS], LX, 0),
+ 'size ' + IntToStr(Sizes[LS]) + ' trial ' + IntToStr(LT));
+ end;
+ end;
+ finally
+ LRandom := nil;
+ end;
+end;
+
+initialization
+
+{$IFDEF FPC}
+ RegisterTest(TTestBinPoly);
+{$ELSE}
+ RegisterTest(TTestBinPoly.Suite);
+{$ENDIF FPC}
+
+end.
diff --git a/CryptoLib.Tests/src/Math/EC/Rfc7748/X25519Tests.pas b/CryptoLib.Tests/src/Math/EC/Rfc7748/X25519Tests.pas
index 9be4f11f..33a0669f 100644
--- a/CryptoLib.Tests/src/Math/EC/Rfc7748/X25519Tests.pas
+++ b/CryptoLib.Tests/src/Math/EC/Rfc7748/X25519Tests.pas
@@ -156,7 +156,6 @@ procedure TTestX25519.SetUp;
begin
inherited SetUp();
FRandom := TSecureRandom.Create();
- TX25519.Precompute();
end;
procedure TTestX25519.TearDown;
diff --git a/CryptoLib.Tests/src/Math/EC/Rfc7748/X448Tests.pas b/CryptoLib.Tests/src/Math/EC/Rfc7748/X448Tests.pas
index ddc9bb29..b0fa55cc 100644
--- a/CryptoLib.Tests/src/Math/EC/Rfc7748/X448Tests.pas
+++ b/CryptoLib.Tests/src/Math/EC/Rfc7748/X448Tests.pas
@@ -156,7 +156,6 @@ procedure TTestX448.SetUp;
begin
inherited SetUp();
FRandom := TSecureRandom.Create();
- TX448.Precompute();
end;
procedure TTestX448.TearDown;
diff --git a/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed25519Tests.pas b/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed25519Tests.pas
index 734baac1..f8e21f7e 100644
--- a/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed25519Tests.pas
+++ b/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed25519Tests.pas
@@ -54,11 +54,15 @@ TTestEd25519 = class(TCryptoLibAlgorithmTestCase)
procedure CheckEd25519phVector(const ASK, APK, AM, ACTX, ASig, AText: String);
procedure ImplTamingVector(ANumber: Int32; AExpected: Boolean; const AMsgHex, APubHex, ASigHex: String); overload;
function ImplTamingVector(const AMsgHex, APubHex, ASigHex: String): Boolean; overload;
+ procedure ImplTestEd25519ConsistencyExpandedKey(AEd25519: TEd25519);
protected
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestEd25519Consistency();
+ procedure TestEd25519ConsistencyExpandedKey();
+ procedure TestEd25519ConsistencyExpandedKeyBlake2b();
+ procedure TestEd25519ExpandedKeyBlake2bPinnedVector();
procedure TestEd25519ConsistencyDefaultMatchesSHA512Digest();
procedure TestEd25519ctxConsistency();
procedure TestEd25519phConsistency();
@@ -306,7 +310,6 @@ function TTestEd25519.ImplTamingVector(const AMsgHex, APubHex,
procedure TTestEd25519.SetUp;
begin
inherited;
- TEd25519.Precompute();
FRandom := TSecureRandom.Create();
FEd25519 := TEd25519.Create();
FEd25519Blake2b := TEd25519Blake2b.Create();
@@ -372,6 +375,121 @@ procedure TTestEd25519.TestEd25519Consistency;
end;
end;
+procedure TTestEd25519.ImplTestEd25519ConsistencyExpandedKey(AEd25519: TEd25519);
+var
+ LExp: TEd25519.TExpandedKey;
+ LXk, LPk, LPk2, LM, LSig1, LSig2: TBytes;
+ LPublicPoint: TEd25519.IPublicPoint;
+ I, LMLen: Int32;
+ LShouldVerify, LShouldNotVerify: Boolean;
+begin
+ System.SetLength(LXk, TEd25519.TExpandedKey.ExpandedKeySize);
+ System.SetLength(LPk, TEd25519.PublicKeySize);
+ System.SetLength(LPk2, TEd25519.PublicKeySize);
+ System.SetLength(LM, 255);
+ System.SetLength(LSig1, TEd25519.SignatureSize);
+ System.SetLength(LSig2, TEd25519.SignatureSize);
+
+ FRandom.NextBytes(LM);
+
+ LExp := AEd25519.CreateExpandedKey;
+ try
+ for I := 0 to 9 do
+ begin
+ LExp.GeneratePrivateKey(FRandom, LXk, 0);
+ LPublicPoint := LExp.GeneratePublicKey(LXk, 0);
+ TEd25519.EncodePublicPoint(LPublicPoint, LPk, 0);
+
+ LExp.GeneratePublicKey(LXk, 0, LPk2, 0);
+ CheckTrue(AreEqual(LPk, LPk2),
+ Format('Ed25519.ExpandedKey consistent generation #%d', [I]));
+
+ LMLen := FRandom.NextInt32() and 255;
+
+ LExp.Sign(LXk, 0, LM, 0, LMLen, LSig1, 0);
+ LExp.Sign(LXk, 0, LPk, 0, LM, 0, LMLen, LSig2, 0);
+
+ CheckTrue(AreEqual(LSig1, LSig2),
+ Format('Ed25519.ExpandedKey consistent signatures #%d', [I]));
+
+ LShouldVerify := AEd25519.Verify(LSig1, 0, LPk, 0, LM, 0, LMLen);
+ CheckTrue(LShouldVerify,
+ Format('Ed25519.ExpandedKey consistent sign/verify #%d', [I]));
+
+ LShouldVerify := AEd25519.Verify(LSig1, 0, LPublicPoint, LM, 0, LMLen);
+ CheckTrue(LShouldVerify,
+ Format('Ed25519.ExpandedKey consistent sign/verify #%d', [I]));
+
+ LSig1[TEd25519.PublicKeySize - 1] := Byte(LSig1[TEd25519.PublicKeySize - 1]
+ xor $80);
+
+ LShouldNotVerify := AEd25519.Verify(LSig1, 0, LPk, 0, LM, 0, LMLen);
+ CheckFalse(LShouldNotVerify,
+ Format('Ed25519.ExpandedKey consistent verification failure #%d', [I]));
+
+ LShouldNotVerify := AEd25519.Verify(LSig1, 0, LPublicPoint, LM, 0, LMLen);
+ CheckFalse(LShouldNotVerify,
+ Format('Ed25519.ExpandedKey consistent verification failure #%d', [I]));
+ end;
+ finally
+ LExp.Free;
+ end;
+end;
+
+procedure TTestEd25519.TestEd25519ConsistencyExpandedKey;
+begin
+ ImplTestEd25519ConsistencyExpandedKey(FEd25519);
+end;
+
+procedure TTestEd25519.TestEd25519ConsistencyExpandedKeyBlake2b;
+begin
+ ImplTestEd25519ConsistencyExpandedKey(FEd25519Blake2b);
+end;
+
+procedure TTestEd25519.TestEd25519ExpandedKeyBlake2bPinnedVector;
+const
+ SkHex =
+ '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60';
+ XkHex =
+ '677103fd64eff7f3ba7f5f94eae42201cb36e62f40a6757157b1fb9c36dfb6fd' +
+ '181df9c90a9d265dba1b664f77644954ae8fe8bbd8d91a2da1f6ee3b23b0f41f';
+ PkHex =
+ '78e65bf30f893d32fc57ef051c341bdede242544fc2a2112f0fa2c7afdebc02f';
+ SigHex =
+ '99a523bd4616c8161144d6a99d3c32400cb4a326f4d79e307340f6afa11750a' +
+ '0085d7d84626bc9e4b153fc0e396d15ce44c39bae4533804db1fe5b52f2b1b805';
+var
+ LExp: TEd25519.TExpandedKey;
+ LSk, LXk, LXk2, LPk, LM, LSigExpanded, LSigSeed: TBytes;
+begin
+ LSk := DecodeHex(SkHex);
+ LXk := DecodeHex(XkHex);
+ LPk := DecodeHex(PkHex);
+ LM := DecodeHex('');
+ LSigSeed := DecodeHex(SigHex);
+
+ LExp := FEd25519Blake2b.CreateExpandedKey;
+ try
+ System.SetLength(LXk2, TEd25519.TExpandedKey.ExpandedKeySize);
+ LExp.ExpandPrivateKey(LSk, 0, LXk2, 0);
+ CheckTrue(AreEqual(LXk, LXk2), 'Blake2b ExpandedKey expand must match BLAKE2b-512(seed)');
+
+ System.SetLength(LSigExpanded, TEd25519.SignatureSize);
+ LExp.Sign(LXk, 0, LM, 0, System.Length(LM), LSigExpanded, 0);
+ CheckTrue(AreEqual(LSigSeed, LSigExpanded),
+ 'Blake2b ExpandedKey sign must match seed-path signature');
+
+ FEd25519Blake2b.Sign(LSk, 0, LM, 0, System.Length(LM), LSigSeed, 0);
+ CheckTrue(AreEqual(LSigSeed, LSigExpanded),
+ 'Blake2b seed-path sign must match ExpandedKey signature');
+
+ CheckTrue(FEd25519Blake2b.Verify(LSigExpanded, 0, LPk, 0, LM, 0, System.Length(LM)),
+ 'Blake2b ExpandedKey signature must verify');
+ finally
+ LExp.Free;
+ end;
+end;
+
procedure TTestEd25519.TestEd25519ctxConsistency;
var
LSk, LPk, LPk2, LCtx, LM, LSig1, LSig2: TBytes;
diff --git a/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed448Tests.pas b/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed448Tests.pas
index 11e357b6..ebb54613 100644
--- a/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed448Tests.pas
+++ b/CryptoLib.Tests/src/Math/EC/Rfc8032/Ed448Tests.pas
@@ -181,7 +181,6 @@ procedure TTestEd448.CheckEd448phVector(const ASK, APK, AM, ACTX, ASig, AText: S
procedure TTestEd448.SetUp;
begin
inherited;
- TEd448.Precompute();
FRandom := TSecureRandom.Create();
FEd448 := TEd448.Create();
FEd448Xof := TEd448Shake256.Create();
diff --git a/CryptoLib.Tests/src/Misc/BinaryPrimitivesTests.pas b/CryptoLib.Tests/src/Misc/BinaryPrimitivesTests.pas
new file mode 100644
index 00000000..304977cd
--- /dev/null
+++ b/CryptoLib.Tests/src/Misc/BinaryPrimitivesTests.pas
@@ -0,0 +1,225 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit BinaryPrimitivesTests;
+
+interface
+
+uses
+ SysUtils,
+{$IFDEF FPC}
+ fpcunit,
+ testregistry,
+{$ELSE}
+ TestFramework,
+{$ENDIF FPC}
+ ClpBinaryPrimitives,
+ CryptoLibTestBase;
+
+type
+
+ TTestBinaryPrimitives = class(TCryptoLibTestCase)
+ published
+ procedure TestUInt16LittleEndianArrayVsPointer;
+ procedure TestUInt16BigEndianArrayVsPointer;
+ procedure TestUInt32LittleEndianArrayVsPointer;
+ procedure TestUInt32BigEndianArrayVsPointer;
+ procedure TestUInt64LittleEndianArrayVsPointer;
+ procedure TestUInt64BigEndianArrayVsPointer;
+ procedure TestUInt32MisalignedPointerRead;
+ procedure TestCopyUInt32LittleEndianAligned;
+ procedure TestCopyUInt32LittleEndianMisaligned;
+ procedure TestCopyUInt32BigEndianWireFormat;
+ procedure TestCopyUInt64LittleEndianAligned;
+ end;
+
+implementation
+
+const
+ TEST_UINT16 = UInt16($1122);
+ TEST_UINT32 = UInt32($11223344);
+ TEST_UINT64 = UInt64($1122334455667788);
+
+procedure TTestBinaryPrimitives.TestUInt16LittleEndianArrayVsPointer;
+var
+ LBuf: TBytes;
+ LFromArray, LFromPointer: UInt16;
+begin
+ SetLength(LBuf, 4);
+ TBinaryPrimitives.WriteUInt16LittleEndian(LBuf, 1, TEST_UINT16);
+ LFromArray := TBinaryPrimitives.ReadUInt16LittleEndian(LBuf, 1);
+ LFromPointer := TBinaryPrimitives.ReadUInt16LittleEndian(PByte(@LBuf[1]), 0);
+ CheckEquals(TEST_UINT16, LFromArray);
+ CheckEquals(LFromArray, LFromPointer);
+ CheckEquals(Byte(TEST_UINT16), LBuf[1]);
+ CheckEquals(Byte(TEST_UINT16 shr 8), LBuf[2]);
+end;
+
+procedure TTestBinaryPrimitives.TestUInt16BigEndianArrayVsPointer;
+var
+ LBuf: TBytes;
+ LFromArray, LFromPointer: UInt16;
+begin
+ SetLength(LBuf, 4);
+ TBinaryPrimitives.WriteUInt16BigEndian(LBuf, 1, TEST_UINT16);
+ LFromArray := TBinaryPrimitives.ReadUInt16BigEndian(LBuf, 1);
+ LFromPointer := TBinaryPrimitives.ReadUInt16BigEndian(PByte(@LBuf[1]), 0);
+ CheckEquals(TEST_UINT16, LFromArray);
+ CheckEquals(LFromArray, LFromPointer);
+ CheckEquals(Byte(TEST_UINT16 shr 8), LBuf[1]);
+ CheckEquals(Byte(TEST_UINT16), LBuf[2]);
+end;
+
+procedure TTestBinaryPrimitives.TestUInt32LittleEndianArrayVsPointer;
+var
+ LBuf: TBytes;
+ LFromArray, LFromPointer: UInt32;
+begin
+ SetLength(LBuf, 8);
+ TBinaryPrimitives.WriteUInt32LittleEndian(LBuf, 2, TEST_UINT32);
+ LFromArray := TBinaryPrimitives.ReadUInt32LittleEndian(LBuf, 2);
+ LFromPointer := TBinaryPrimitives.ReadUInt32LittleEndian(PByte(@LBuf[2]), 0);
+ CheckEquals(TEST_UINT32, LFromArray);
+ CheckEquals(LFromArray, LFromPointer);
+end;
+
+procedure TTestBinaryPrimitives.TestUInt32BigEndianArrayVsPointer;
+var
+ LBuf: TBytes;
+ LFromArray, LFromPointer: UInt32;
+begin
+ SetLength(LBuf, 8);
+ TBinaryPrimitives.WriteUInt32BigEndian(LBuf, 2, TEST_UINT32);
+ LFromArray := TBinaryPrimitives.ReadUInt32BigEndian(LBuf, 2);
+ LFromPointer := TBinaryPrimitives.ReadUInt32BigEndian(PByte(@LBuf[2]), 0);
+ CheckEquals(TEST_UINT32, LFromArray);
+ CheckEquals(LFromArray, LFromPointer);
+end;
+
+procedure TTestBinaryPrimitives.TestUInt64LittleEndianArrayVsPointer;
+var
+ LBuf: TBytes;
+ LFromArray, LFromPointer: UInt64;
+begin
+ SetLength(LBuf, 16);
+ TBinaryPrimitives.WriteUInt64LittleEndian(LBuf, 4, TEST_UINT64);
+ LFromArray := TBinaryPrimitives.ReadUInt64LittleEndian(LBuf, 4);
+ LFromPointer := TBinaryPrimitives.ReadUInt64LittleEndian(PByte(@LBuf[4]), 0);
+ CheckEquals(TEST_UINT64, LFromArray);
+ CheckEquals(LFromArray, LFromPointer);
+end;
+
+procedure TTestBinaryPrimitives.TestUInt64BigEndianArrayVsPointer;
+var
+ LBuf: TBytes;
+ LFromArray, LFromPointer: UInt64;
+begin
+ SetLength(LBuf, 16);
+ TBinaryPrimitives.WriteUInt64BigEndian(LBuf, 4, TEST_UINT64);
+ LFromArray := TBinaryPrimitives.ReadUInt64BigEndian(LBuf, 4);
+ LFromPointer := TBinaryPrimitives.ReadUInt64BigEndian(PByte(@LBuf[4]), 0);
+ CheckEquals(TEST_UINT64, LFromArray);
+ CheckEquals(LFromArray, LFromPointer);
+end;
+
+procedure TTestBinaryPrimitives.TestUInt32MisalignedPointerRead;
+var
+ LBuf: TBytes;
+ LValue: UInt32;
+begin
+ SetLength(LBuf, 9);
+ LBuf[0] := $AA;
+ TBinaryPrimitives.WriteUInt32LittleEndian(LBuf, 1, TEST_UINT32);
+ LValue := TBinaryPrimitives.ReadUInt32LittleEndian(PByte(@LBuf[0]), 1);
+ CheckEquals(TEST_UINT32, LValue);
+
+ FillChar(LBuf[0], Length(LBuf), 0);
+ LBuf[0] := $AA;
+ TBinaryPrimitives.WriteUInt32BigEndian(LBuf, 1, TEST_UINT32);
+ LValue := TBinaryPrimitives.ReadUInt32BigEndian(PByte(@LBuf[0]), 1);
+ CheckEquals(TEST_UINT32, LValue);
+end;
+
+procedure TTestBinaryPrimitives.TestCopyUInt32LittleEndianAligned;
+var
+ LSource, LDest: TBytes;
+ LI: Integer;
+begin
+ SetLength(LSource, 12);
+ SetLength(LDest, 12);
+ for LI := 0 to 11 do
+ LSource[LI] := Byte(LI + 1);
+ FillChar(LDest[0], Length(LDest), 0);
+ TBinaryPrimitives.CopyUInt32LittleEndian(@LSource[0], 0, @LDest[0], 0, 12);
+ for LI := 0 to 11 do
+ CheckEquals(LSource[LI], LDest[LI], Format('byte %d', [LI]));
+end;
+
+procedure TTestBinaryPrimitives.TestCopyUInt32LittleEndianMisaligned;
+var
+ LSource, LDest: TBytes;
+ LI: Integer;
+begin
+ SetLength(LSource, 14);
+ SetLength(LDest, 14);
+ for LI := 0 to 13 do
+ LSource[LI] := Byte(LI + $10);
+ FillChar(LDest[0], Length(LDest), 0);
+ TBinaryPrimitives.CopyUInt32LittleEndian(@LSource[0], 1, @LDest[0], 2, 8);
+ for LI := 0 to 7 do
+ CheckEquals(LSource[1 + LI], LDest[2 + LI], Format('byte %d', [LI]));
+end;
+
+procedure TTestBinaryPrimitives.TestCopyUInt32BigEndianWireFormat;
+var
+ LSource, LDest: TBytes;
+ LWireValue, LNativeValue: UInt32;
+begin
+ SetLength(LSource, 4);
+ SetLength(LDest, 4);
+ LWireValue := UInt32($11223344);
+ TBinaryPrimitives.WriteUInt32BigEndian(LSource, 0, LWireValue);
+ FillChar(LDest[0], 4, 0);
+ TBinaryPrimitives.CopyUInt32BigEndian(@LSource[0], 0, @LDest[0], 0, 4);
+ // On LE hosts, CopyUInt32BigEndian byte-reverses into dest; LE read recovers the wire value
+ LNativeValue := TBinaryPrimitives.ReadUInt32LittleEndian(LDest, 0);
+ CheckEquals(LWireValue, LNativeValue);
+end;
+
+procedure TTestBinaryPrimitives.TestCopyUInt64LittleEndianAligned;
+var
+ LSource, LDest: TBytes;
+ LI: Integer;
+begin
+ SetLength(LSource, 16);
+ SetLength(LDest, 16);
+ for LI := 0 to 15 do
+ LSource[LI] := Byte(LI + $20);
+ FillChar(LDest[0], Length(LDest), 0);
+ TBinaryPrimitives.CopyUInt64LittleEndian(@LSource[0], 0, @LDest[0], 0, 16);
+ for LI := 0 to 15 do
+ CheckEquals(LSource[LI], LDest[LI], Format('byte %d', [LI]));
+end;
+
+initialization
+
+{$IFDEF FPC}
+ RegisterTest(TTestBinaryPrimitives);
+{$ELSE}
+ RegisterTest(TTestBinaryPrimitives.Suite);
+{$ENDIF FPC}
+
+end.
diff --git a/CryptoLib.Tests/src/Others/ECDsa5Tests.pas b/CryptoLib.Tests/src/Others/ECDsa5Tests.pas
index 8dd582f4..9e7b8e8e 100644
--- a/CryptoLib.Tests/src/Others/ECDsa5Tests.pas
+++ b/CryptoLib.Tests/src/Others/ECDsa5Tests.pas
@@ -176,8 +176,10 @@ procedure TTestECDsa5.TestECDsa239BitBinary;
TBigInteger.Create
('32010857077C5431123A46B808906756F543423E8D27877578125778AC76', 16), // a
TBigInteger.Create
- ('790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16', 16) // b
- );
+ ('790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16', 16), // b
+ TBigInteger.Create
+ ('220855883097298041197912187592864814557886993776713230936715041207411783', 10), // n
+ TBigInteger.ValueOf(4)); // h
parameters := TECDomainParameters.Create(curve,
curve.DecodePoint
diff --git a/CryptoLib.Tests/src/Others/ECTests.pas b/CryptoLib.Tests/src/Others/ECTests.pas
index a344b647..3be51454 100644
--- a/CryptoLib.Tests/src/Others/ECTests.pas
+++ b/CryptoLib.Tests/src/Others/ECTests.pas
@@ -386,8 +386,10 @@ procedure TTestEC.TestECDsa239BitBinary;
TBigInteger.Create
('32010857077C5431123A46B808906756F543423E8D27877578125778AC76', 16), // a
TBigInteger.Create
- ('790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16', 16) // b
- );
+ ('790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16', 16), // b
+ TBigInteger.Create
+ ('220855883097298041197912187592864814557886993776713230936715041207411783', 10), // n
+ TBigInteger.ValueOf(4)); // h
parameters := TECDomainParameters.Create(curve,
curve.DecodePoint
@@ -471,8 +473,10 @@ procedure TTestEC.TestECDsa239BitBinaryAndLargeDigest;
TBigInteger.Create
('32010857077C5431123A46B808906756F543423E8D27877578125778AC76', 16), // a
TBigInteger.Create
- ('790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16', 16) // b
- );
+ ('790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16', 16), // b
+ TBigInteger.Create
+ ('220855883097298041197912187592864814557886993776713230936715041207411783', 10), // n
+ TBigInteger.ValueOf(4)); // h
parameters := TECDomainParameters.Create(curve,
curve.DecodePoint
diff --git a/CryptoLib.Tests/src/Others/Ed25519HigherLevelTests.pas b/CryptoLib.Tests/src/Others/Ed25519HigherLevelTests.pas
index 2f84eb3b..dda80ce8 100644
--- a/CryptoLib.Tests/src/Others/Ed25519HigherLevelTests.pas
+++ b/CryptoLib.Tests/src/Others/Ed25519HigherLevelTests.pas
@@ -43,7 +43,6 @@ interface
ClpSecureRandom,
ClpISecureRandom,
ClpICipherParameters,
- ClpStringUtilities,
ClpCryptoLibTypes,
CryptoLibTestBase,
AsymmetricTestVectors;
diff --git a/CryptoLib.Tests/src/Others/Ed448HigherLevelTests.pas b/CryptoLib.Tests/src/Others/Ed448HigherLevelTests.pas
index e717471c..2a2f1cc4 100644
--- a/CryptoLib.Tests/src/Others/Ed448HigherLevelTests.pas
+++ b/CryptoLib.Tests/src/Others/Ed448HigherLevelTests.pas
@@ -42,7 +42,6 @@ interface
ClpSecureRandom,
ClpISecureRandom,
ClpICipherParameters,
- ClpStringUtilities,
ClpCryptoLibTypes,
CryptoLibTestBase,
AsymmetricTestVectors;
diff --git a/CryptoLib.Tests/src/Pkcs/Pkcs12StoreTests.pas b/CryptoLib.Tests/src/Pkcs/Pkcs12StoreTests.pas
index d2898968..6032c2d2 100644
--- a/CryptoLib.Tests/src/Pkcs/Pkcs12StoreTests.pas
+++ b/CryptoLib.Tests/src/Pkcs/Pkcs12StoreTests.pas
@@ -61,6 +61,7 @@ interface
ClpIX509Generators,
ClpAsn1SignatureFactory,
ClpGeneratorUtilities,
+ ClpPrivateKeyInfoFactory,
ClpIAsymmetricCipherKeyPairGenerator,
ClpIAsymmetricCipherKeyPair,
ClpIAsymmetricKeyParameter,
@@ -99,6 +100,7 @@ TTestPkcs12Store = class(TCryptoLibAlgorithmTestCase)
FSentrix1: TBytes;
FSentrix2: TBytes;
FSentrix3: TBytes;
+ FRawKeyBagStore: TBytes;
function CreateCert(const APubKey, APrivKey: IAsymmetricKeyParameter;
const AIssuerEmail, ASubjectEmail: String; const ALocalKeyId: TBytes): IX509CertificateEntry;
@@ -118,6 +120,7 @@ TTestPkcs12Store = class(TCryptoLibAlgorithmTestCase)
procedure LoadStoreFromBytes(const AStore: IPkcs12Store; const AData: TBytes;
const APassword: TCryptoLibCharArray);
function SaveStoreToBytes(const AStore: IPkcs12Store; const APassword: TCryptoLibCharArray): TBytes;
+ function CreateKeyBagPfx(const ASafeBag: ISafeBag): TBytes;
procedure LoadSentrixStoreAndCheck(const AData: TBytes; const APassword: TCryptoLibCharArray);
function GetExpectedPkcs12Modulus: TBigInteger;
function GetExpectedPkcs12ChainSerial(AIndex: Int32): TBigInteger;
@@ -148,6 +151,9 @@ TTestPkcs12Store = class(TCryptoLibAlgorithmTestCase)
procedure TestFriendlyName_OverwriteFalse_AddedFriendlyName_Persisted;
procedure TestPkcs12Store_MissingContentInfoContent;
procedure TestPkcs12Store_NegativeIterations;
+ procedure TestRawKeyBagNoAttributes;
+ procedure TestRawKeyBagStore;
+ procedure TestWrongPassword;
end;
implementation
@@ -178,6 +184,7 @@ procedure TTestPkcs12Store.SetUp;
FSentrix1 := TPkcs12StoreVectors.LoadStoreBytes('Sentrix1');
FSentrix2 := TPkcs12StoreVectors.LoadStoreBytes('Sentrix2');
FSentrix3 := TPkcs12StoreVectors.LoadStoreBytes('Sentrix3');
+ FRawKeyBagStore := TPkcs12StoreVectors.LoadStoreBytes('RawKeyBagStore');
end;
function TTestPkcs12Store.GetFirst(const AAliases: TCryptoLibStringArray): String;
@@ -253,6 +260,22 @@ function TTestPkcs12Store.SaveStoreToBytes(const AStore: IPkcs12Store; const APa
end;
end;
+function TTestPkcs12Store.CreateKeyBagPfx(const ASafeBag: ISafeBag): TBytes;
+var
+ LDataInfo, LMainInfo: IPkcsContentInfo;
+ LAuthSafe: IAuthenticatedSafe;
+ LCInfos: TCryptoLibGenericArray;
+begin
+ LDataInfo := TPkcsContentInfo.Create(TPkcsObjectIdentifiers.Data,
+ TDerOctetString.Create((TDerSequence.Create(ASafeBag) as IDerSequence).GetEncoded()) as IDerOctetString);
+ SetLength(LCInfos, 1);
+ LCInfos[0] := LDataInfo;
+ LAuthSafe := TAuthenticatedSafe.Create(LCInfos);
+ LMainInfo := TPkcsContentInfo.Create(TPkcsObjectIdentifiers.Data,
+ TDerOctetString.Create(LAuthSafe.GetEncoded()) as IDerOctetString);
+ Result := (TPfx.Create(LMainInfo, nil) as IPfx).GetEncoded();
+end;
+
procedure TTestPkcs12Store.LoadSentrixStoreAndCheck(const AData: TBytes; const APassword: TCryptoLibCharArray);
var
LStore: IPkcs12Store;
@@ -1053,6 +1076,77 @@ procedure TTestPkcs12Store.TestPkcs12Store_MissingContentInfoContent;
end;
end;
+procedure TTestPkcs12Store.TestRawKeyBagNoAttributes;
+var
+ LKpg: IAsymmetricCipherKeyPairGenerator;
+ LKeyPair: IAsymmetricCipherKeyPair;
+ LPrivateKeyInfo: IPrivateKeyInfo;
+ LNoAttrBag, LFriendlyBag: ISafeBag;
+ LKeyBagPfxA, LKeyBagPfxB: TBytes;
+ LStoreA, LStoreB: IPkcs12Store;
+ LEmptyPass: TCryptoLibCharArray;
+ LAlias: String;
+ LFriendlyName: IAsn1Encodable;
+begin
+ // RFC 7292 sec. 4.2.1 keyBag (unencrypted PrivateKeyInfo) may carry no bagAttributes, and the localKeyId
+ // attribute is optional even when bagAttributes are present. Ensure correct handling.
+ LKpg := TGeneratorUtilities.GetKeyPairGenerator('RSA');
+ LKpg.Init(TRsaKeyGenerationParameters.Create(TBigInteger.ValueOf(Int64($10001)), FRandom, 1024, 25) as IRsaKeyGenerationParameters);
+ LKeyPair := LKpg.GenerateKeyPair;
+ LPrivateKeyInfo := TPrivateKeyInfoFactory.CreatePrivateKeyInfo(LKeyPair.Private);
+
+ // Case A: keyBag with no bagAttributes at all.
+ LNoAttrBag := TSafeBag.Create(TPkcsObjectIdentifiers.KeyBag, LPrivateKeyInfo.ToAsn1Object());
+ LKeyBagPfxA := CreateKeyBagPfx(LNoAttrBag);
+
+ LStoreA := BuildPkcs12Store;
+ LEmptyPass := nil;
+ LoadStoreFromBytes(LStoreA, LKeyBagPfxA, LEmptyPass);
+
+ LAlias := GetFirst(LStoreA.Aliases);
+ Check(LStoreA.IsKeyEntry(LAlias), 'no-attributes keyBag entry not a key');
+ Check(LStoreA.GetKey(LAlias) <> nil, 'no-attributes keyBag key not recoverable');
+
+ // Case B: keyBag carrying a friendlyName but no localKeyId attribute.
+ LFriendlyName := TDerSequence.Create(TPkcsObjectIdentifiers.Pkcs9AtFriendlyName,
+ TDerSet.Create(TDerBmpString.Create('rawKeyBag') as IDerBmpString) as IDerSet);
+ LFriendlyBag := TSafeBag.Create(TPkcsObjectIdentifiers.KeyBag, LPrivateKeyInfo.ToAsn1Object(),
+ TDerSet.Create(LFriendlyName) as IDerSet);
+ LKeyBagPfxB := CreateKeyBagPfx(LFriendlyBag);
+
+ LStoreB := BuildPkcs12Store;
+ LoadStoreFromBytes(LStoreB, LKeyBagPfxB, LEmptyPass);
+ Check(LStoreB.IsKeyEntry('rawKeyBag'), 'friendlyName keyBag not stored under its alias');
+ Check(LStoreB.GetKey('rawKeyBag') <> nil, 'friendlyName keyBag key not recoverable');
+end;
+
+procedure TTestPkcs12Store.TestRawKeyBagStore;
+var
+ LStore: IPkcs12Store;
+ LEmptyPass: TCryptoLibCharArray;
+begin
+ LStore := BuildPkcs12Store;
+ LEmptyPass := nil;
+ LoadStoreFromBytes(LStore, FRawKeyBagStore, LEmptyPass);
+ Check(LStore.IsKeyEntry('ONVIF_Test_Alias'), 'expected ONVIF_Test_Alias key entry');
+end;
+
+procedure TTestPkcs12Store.TestWrongPassword;
+var
+ LStore: IPkcs12Store;
+begin
+ LStore := BuildPkcs12Store;
+ try
+ LoadStoreFromBytes(LStore, FPkcs12, StringToCharArray('Goodbye World!'));
+ Fail('expected EIOCryptoLibException');
+ except
+ on E: EIOCryptoLibException do
+ ;
+ else
+ raise;
+ end;
+end;
+
initialization
{$IFDEF FPC}
diff --git a/CryptoLib.Tests/src/Utils/FixedSecureRandom.pas b/CryptoLib.Tests/src/Utils/FixedSecureRandom.pas
index 88e261cb..a8234b7e 100644
--- a/CryptoLib.Tests/src/Utils/FixedSecureRandom.pas
+++ b/CryptoLib.Tests/src/Utils/FixedSecureRandom.pas
@@ -75,8 +75,7 @@ TFixedSecureRandom = class(TSecureRandom, IFixedSecureRandom)
FisAndroidStyle, FisClasspathStyle, FisRegularStyle: Boolean;
- class procedure Boot(); static;
- class constructor FixedSecureRandom();
+ class constructor Create();
type
TRandomChecker = class(TSecureRandom, IRandomChecker)
@@ -176,7 +175,7 @@ constructor TFixedSecureRandom.Create(const data: TCryptoLibByteArray);
F_data := data;
end;
-class procedure TFixedSecureRandom.Boot;
+class constructor TFixedSecureRandom.Create;
var
Fcheck1, Fcheck2: TBigInteger;
begin
@@ -376,11 +375,6 @@ class function TFixedSecureRandom.ExpandToBitLength(bitLength: Int32;
result := lv;
end;
-class constructor TFixedSecureRandom.FixedSecureRandom;
-begin
- TFixedSecureRandom.Boot;
-end;
-
class function TFixedSecureRandom.From(const values: TCryptoLibMatrixByteArray)
: IFixedSecureRandom;
var
diff --git a/CryptoLib.Tests/src/Utils/NumberUtilities/ByteUtilitiesTests.pas b/CryptoLib.Tests/src/Utils/NumberUtilities/ByteUtilitiesTests.pas
new file mode 100644
index 00000000..d26551ab
--- /dev/null
+++ b/CryptoLib.Tests/src/Utils/NumberUtilities/ByteUtilitiesTests.pas
@@ -0,0 +1,117 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ByteUtilitiesTests;
+
+interface
+
+uses
+ SysUtils,
+{$IFDEF FPC}
+ fpcunit,
+ testregistry,
+{$ELSE}
+ TestFramework,
+{$ENDIF FPC}
+ ClpByteUtilities,
+ CryptoLibTestBase;
+
+type
+ TTestByteUtilities = class(TCryptoLibAlgorithmTestCase)
+ published
+ procedure TestArrayVsPointerXor16;
+ procedure TestMisalignedPointerXor;
+ procedure TestXorToVsThreeWayXor;
+ end;
+
+implementation
+
+procedure FillPattern(var ABuf: TBytes; AStart: Byte);
+var
+ LI: Integer;
+begin
+ for LI := 0 to System.Length(ABuf) - 1 do
+ ABuf[LI] := Byte(AStart + LI);
+end;
+
+procedure TTestByteUtilities.TestArrayVsPointerXor16;
+var
+ LX, LY, LFromArray, LFromPointer: TBytes;
+ LI: Integer;
+begin
+ SetLength(LX, 16);
+ SetLength(LY, 16);
+ SetLength(LFromArray, 16);
+ SetLength(LFromPointer, 16);
+ FillPattern(LX, $10);
+ FillPattern(LY, $A0);
+
+ TByteUtilities.&Xor(16, LX, LY, LFromArray);
+ TByteUtilities.&Xor(16, PByte(LX), PByte(LY), PByte(LFromPointer));
+
+ CheckTrue(AreEqual(LFromArray, LFromPointer), 'array and pointer Xor must match');
+ for LI := 0 to 15 do
+ CheckEquals(Byte(LX[LI] xor LY[LI]), LFromArray[LI]);
+end;
+
+procedure TTestByteUtilities.TestMisalignedPointerXor;
+var
+ LX, LY, LExpected, LActual: TBytes;
+ LI: Integer;
+begin
+ SetLength(LX, 17);
+ SetLength(LY, 17);
+ SetLength(LExpected, 16);
+ SetLength(LActual, 16);
+ FillPattern(LX, $21);
+ FillPattern(LY, $43);
+
+ for LI := 0 to 15 do
+ LExpected[LI] := Byte(LX[1 + LI] xor LY[1 + LI]);
+
+ TByteUtilities.&Xor(16, PByte(LX), PByte(LY), PByte(LActual), 1, 1, 0);
+ CheckTrue(AreEqual(LExpected, LActual), 'misaligned pointer Xor must match byte reference');
+end;
+
+procedure TTestByteUtilities.TestXorToVsThreeWayXor;
+var
+ LX, LY, LFromXor, LFromXorTo: TBytes;
+begin
+ SetLength(LX, 16);
+ SetLength(LY, 16);
+ SetLength(LFromXor, 16);
+ SetLength(LFromXorTo, 16);
+ FillPattern(LX, $55);
+ FillPattern(LY, $66);
+
+ TByteUtilities.&Xor(16, LX, LY, LFromXor);
+
+ FillChar(LFromXorTo[0], 16, 0);
+ TByteUtilities.XorTo(16, LX, LFromXorTo);
+ TByteUtilities.XorTo(16, LY, LFromXorTo);
+
+ CheckTrue(AreEqual(LFromXor, LFromXorTo), 'XorTo accumulate must match three-way Xor');
+end;
+
+initialization
+
+{$IFDEF FPC}
+ RegisterTest(TTestByteUtilities);
+{$ELSE}
+ RegisterTest(TTestByteUtilities.Suite);
+{$ENDIF FPC}
+
+end.
diff --git a/CryptoLib/src/Asn1/Bc/ClpBcObjectIdentifiers.pas b/CryptoLib/src/Asn1/Bc/ClpBcObjectIdentifiers.pas
index 76d79d60..4dd7cdaf 100644
--- a/CryptoLib/src/Asn1/Bc/ClpBcObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Bc/ClpBcObjectIdentifiers.pas
@@ -28,7 +28,6 @@ interface
TBcObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FBc, FBcPbe,
FBcPbeSha1, FBcPbeSha256, FBcPbeSha384, FBcPbeSha512, FBcPbeSha224,
FBcPbeSha1Pkcs5, FBcPbeSha1Pkcs12,
@@ -91,8 +90,6 @@ TBcObjectIdentifiers = class abstract(TObject)
class property BcPbeSha256Pkcs12Aes192Cbc: IDerObjectIdentifier read GetBcPbeSha256Pkcs12Aes192Cbc;
/// 1.3.6.1.4.1.22554.1.1.2.2.42
class property BcPbeSha256Pkcs12Aes256Cbc: IDerObjectIdentifier read GetBcPbeSha256Pkcs12Aes256Cbc;
-
- class procedure Boot; static;
end;
implementation
@@ -101,33 +98,23 @@ implementation
class constructor TBcObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TBcObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FBc := TDerObjectIdentifier.Create('1.3.6.1.4.1.22554');
- FBcPbe := FBc.Branch('1');
- FBcPbeSha1 := FBcPbe.Branch('1');
- FBcPbeSha256 := FBcPbe.Branch('2.1');
- FBcPbeSha384 := FBcPbe.Branch('2.2');
- FBcPbeSha512 := FBcPbe.Branch('2.3');
- FBcPbeSha224 := FBcPbe.Branch('2.4');
- FBcPbeSha1Pkcs5 := FBcPbeSha1.Branch('1');
- FBcPbeSha1Pkcs12 := FBcPbeSha1.Branch('2');
- FBcPbeSha256Pkcs5 := FBcPbeSha256.Branch('1');
- FBcPbeSha256Pkcs12 := FBcPbeSha256.Branch('2');
- FBcPbeSha1Pkcs12Aes128Cbc := FBcPbeSha1Pkcs12.Branch('1.2');
- FBcPbeSha1Pkcs12Aes192Cbc := FBcPbeSha1Pkcs12.Branch('1.22');
- FBcPbeSha1Pkcs12Aes256Cbc := FBcPbeSha1Pkcs12.Branch('1.42');
- FBcPbeSha256Pkcs12Aes128Cbc := FBcPbeSha256Pkcs12.Branch('1.2');
- FBcPbeSha256Pkcs12Aes192Cbc := FBcPbeSha256Pkcs12.Branch('1.22');
- FBcPbeSha256Pkcs12Aes256Cbc := FBcPbeSha256Pkcs12.Branch('1.42');
-
- FIsBooted := True;
- end;
+ FBc := TDerObjectIdentifier.Create('1.3.6.1.4.1.22554');
+ FBcPbe := FBc.Branch('1');
+ FBcPbeSha1 := FBcPbe.Branch('1');
+ FBcPbeSha256 := FBcPbe.Branch('2.1');
+ FBcPbeSha384 := FBcPbe.Branch('2.2');
+ FBcPbeSha512 := FBcPbe.Branch('2.3');
+ FBcPbeSha224 := FBcPbe.Branch('2.4');
+ FBcPbeSha1Pkcs5 := FBcPbeSha1.Branch('1');
+ FBcPbeSha1Pkcs12 := FBcPbeSha1.Branch('2');
+ FBcPbeSha256Pkcs5 := FBcPbeSha256.Branch('1');
+ FBcPbeSha256Pkcs12 := FBcPbeSha256.Branch('2');
+ FBcPbeSha1Pkcs12Aes128Cbc := FBcPbeSha1Pkcs12.Branch('1.2');
+ FBcPbeSha1Pkcs12Aes192Cbc := FBcPbeSha1Pkcs12.Branch('1.22');
+ FBcPbeSha1Pkcs12Aes256Cbc := FBcPbeSha1Pkcs12.Branch('1.42');
+ FBcPbeSha256Pkcs12Aes128Cbc := FBcPbeSha256Pkcs12.Branch('1.2');
+ FBcPbeSha256Pkcs12Aes192Cbc := FBcPbeSha256Pkcs12.Branch('1.22');
+ FBcPbeSha256Pkcs12Aes256Cbc := FBcPbeSha256Pkcs12.Branch('1.42');
end;
class function TBcObjectIdentifiers.GetBc: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Bsi/ClpBsiObjectIdentifiers.pas b/CryptoLib/src/Asn1/Bsi/ClpBsiObjectIdentifiers.pas
index 9e4e872d..e2ba4487 100644
--- a/CryptoLib/src/Asn1/Bsi/ClpBsiObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Bsi/ClpBsiObjectIdentifiers.pas
@@ -29,7 +29,6 @@ interface
TBsiObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FBsiDe, FIdEcc, FAlgorithm, FEcdsaPlainSignatures,
FEcdsaPlainSha1, FEcdsaPlainSha224, FEcdsaPlainSha256, FEcdsaPlainSha384,
FEcdsaPlainSha512, FEcdsaPlainRipeMD160, FEcdsaPlainSha3_224,
@@ -96,8 +95,6 @@ TBsiObjectIdentifiers = class abstract(TObject)
class property EckaEgSessionKdfAes128: IDerObjectIdentifier read GetEckaEgSessionKdfAes128;
class property EckaEgSessionKdfAes192: IDerObjectIdentifier read GetEckaEgSessionKdfAes192;
class property EckaEgSessionKdfAes256: IDerObjectIdentifier read GetEckaEgSessionKdfAes256;
-
- class procedure Boot; static;
end;
implementation
@@ -106,46 +103,36 @@ implementation
class constructor TBsiObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TBsiObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FBsiDe := TDerObjectIdentifier.Create('0.4.0.127.0.7');
- FIdEcc := FBsiDe.Branch('1.1');
- FAlgorithm := FBsiDe.Branch('1');
-
- FEcdsaPlainSignatures := FIdEcc.Branch('4.1');
- FEcdsaPlainSha1 := FEcdsaPlainSignatures.Branch('1');
- FEcdsaPlainSha224 := FEcdsaPlainSignatures.Branch('2');
- FEcdsaPlainSha256 := FEcdsaPlainSignatures.Branch('3');
- FEcdsaPlainSha384 := FEcdsaPlainSignatures.Branch('4');
- FEcdsaPlainSha512 := FEcdsaPlainSignatures.Branch('5');
- FEcdsaPlainRipeMD160 := FEcdsaPlainSignatures.Branch('6');
- FEcdsaPlainSha3_224 := FEcdsaPlainSignatures.Branch('8');
- FEcdsaPlainSha3_256 := FEcdsaPlainSignatures.Branch('9');
- FEcdsaPlainSha3_384 := FEcdsaPlainSignatures.Branch('10');
- FEcdsaPlainSha3_512 := FEcdsaPlainSignatures.Branch('11');
-
- FEckaEg := FIdEcc.Branch('5.1');
- FEckaEgX963Kdf := FEckaEg.Branch('1');
- FEckaEgX963KdfSha1 := FEckaEgX963Kdf.Branch('1');
- FEckaEgX963KdfSha224 := FEckaEgX963Kdf.Branch('2');
- FEckaEgX963KdfSha256 := FEckaEgX963Kdf.Branch('3');
- FEckaEgX963KdfSha384 := FEckaEgX963Kdf.Branch('4');
- FEckaEgX963KdfSha512 := FEckaEgX963Kdf.Branch('5');
- FEckaEgX963KdfRipeMD160 := FEckaEgX963Kdf.Branch('6');
-
- FEckaEgSessionKdf := FEckaEg.Branch('2');
- FEckaEgSessionKdf3Des := FEckaEgSessionKdf.Branch('1');
- FEckaEgSessionKdfAes128 := FEckaEgSessionKdf.Branch('2');
- FEckaEgSessionKdfAes192 := FEckaEgSessionKdf.Branch('3');
- FEckaEgSessionKdfAes256 := FEckaEgSessionKdf.Branch('4');
-
- FIsBooted := True;
- end;
+ FBsiDe := TDerObjectIdentifier.Create('0.4.0.127.0.7');
+ FIdEcc := FBsiDe.Branch('1.1');
+ FAlgorithm := FBsiDe.Branch('1');
+
+ FEcdsaPlainSignatures := FIdEcc.Branch('4.1');
+ FEcdsaPlainSha1 := FEcdsaPlainSignatures.Branch('1');
+ FEcdsaPlainSha224 := FEcdsaPlainSignatures.Branch('2');
+ FEcdsaPlainSha256 := FEcdsaPlainSignatures.Branch('3');
+ FEcdsaPlainSha384 := FEcdsaPlainSignatures.Branch('4');
+ FEcdsaPlainSha512 := FEcdsaPlainSignatures.Branch('5');
+ FEcdsaPlainRipeMD160 := FEcdsaPlainSignatures.Branch('6');
+ FEcdsaPlainSha3_224 := FEcdsaPlainSignatures.Branch('8');
+ FEcdsaPlainSha3_256 := FEcdsaPlainSignatures.Branch('9');
+ FEcdsaPlainSha3_384 := FEcdsaPlainSignatures.Branch('10');
+ FEcdsaPlainSha3_512 := FEcdsaPlainSignatures.Branch('11');
+
+ FEckaEg := FIdEcc.Branch('5.1');
+ FEckaEgX963Kdf := FEckaEg.Branch('1');
+ FEckaEgX963KdfSha1 := FEckaEgX963Kdf.Branch('1');
+ FEckaEgX963KdfSha224 := FEckaEgX963Kdf.Branch('2');
+ FEckaEgX963KdfSha256 := FEckaEgX963Kdf.Branch('3');
+ FEckaEgX963KdfSha384 := FEckaEgX963Kdf.Branch('4');
+ FEckaEgX963KdfSha512 := FEckaEgX963Kdf.Branch('5');
+ FEckaEgX963KdfRipeMD160 := FEckaEgX963Kdf.Branch('6');
+
+ FEckaEgSessionKdf := FEckaEg.Branch('2');
+ FEckaEgSessionKdf3Des := FEckaEgSessionKdf.Branch('1');
+ FEckaEgSessionKdfAes128 := FEckaEgSessionKdf.Branch('2');
+ FEckaEgSessionKdfAes192 := FEckaEgSessionKdf.Branch('3');
+ FEckaEgSessionKdfAes256 := FEckaEgSessionKdf.Branch('4');
end;
class function TBsiObjectIdentifiers.GetAlgorithm: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/ClpAsn1Generators.pas b/CryptoLib/src/Asn1/ClpAsn1Generators.pas
index 50cf04b1..91307730 100644
--- a/CryptoLib/src/Asn1/ClpAsn1Generators.pas
+++ b/CryptoLib/src/Asn1/ClpAsn1Generators.pas
@@ -28,7 +28,6 @@ interface
ClpAsn1Tags,
ClpAsn1Core,
ClpAsn1Streams,
- ClpBitOperations,
ClpStreamUtilities;
type
@@ -67,7 +66,8 @@ TBerGenerator = class abstract(TAsn1Generator, IBerGenerator)
constructor Create(AOutStream: TStream); overload;
constructor Create(AOutStream: TStream; ATagNo: Int32; AIsExplicit: Boolean); overload;
- procedure WriteHdr(ATag: Int32);
+ procedure WriteHdr(ATag: Int32); overload;
+ procedure WriteHdr(AFlags, ATagNo: Int32); overload;
procedure WriteBerHeader(ATag: Int32);
procedure WriteBerBody(AContentStream: TStream);
procedure WriteBerEnd();
@@ -107,14 +107,14 @@ TDerGenerator = class abstract(TAsn1Generator, IDerGenerator)
strict private
FTagged, FIsExplicit: Boolean;
FTagNo: Int32;
- class procedure WriteLength(const AOutStr: TStream; ALength: Int32); static;
+ procedure WriteDerEncoded(const AOutStream: TStream; AFlags, ATagNo: Int32;
+ const ABytes: TCryptoLibByteArray); overload;
strict protected
constructor Create(const AOutStream: TStream); overload;
constructor Create(const AOutStream: TStream; ATagNo: Int32; AIsExplicit: Boolean); overload;
public
procedure WriteDerEncoded(ATag: Int32; const ABytes: TCryptoLibByteArray); overload;
class procedure WriteDerEncoded(const AOutStream: TStream; ATag: Int32; const ABytes: TCryptoLibByteArray); overload; static;
- class procedure WriteDerEncoded(const AOutStr: TStream; ATag: Int32; const AInStr: TStream); overload; static;
end;
///
@@ -256,7 +256,7 @@ procedure TBerGenerator.WriteBerHeader(ATag: Int32);
* X.690-0207 8.14.2. If implicit tagging [..] was not used [..], the encoding shall be constructed
* and the contents octets shall be the complete base encoding.
}
- WriteHdr(FTagNo or TAsn1Tags.ContextSpecific or TAsn1Tags.Constructed);
+ WriteHdr(TAsn1Tags.ContextSpecific or TAsn1Tags.Constructed, FTagNo);
WriteHdr(ATag);
end
else
@@ -266,7 +266,7 @@ procedure TBerGenerator.WriteBerHeader(ATag: Int32);
* if the base encoding is constructed, and shall be primitive otherwise; and b) the contents octets
* shall be [..] the contents octets of the base encoding.
}
- WriteHdr(InheritConstructedFlag(FTagNo or TAsn1Tags.ContextSpecific, ATag));
+ WriteHdr(InheritConstructedFlag(TAsn1Tags.ContextSpecific, ATag), FTagNo);
end;
end;
@@ -276,6 +276,12 @@ procedure TBerGenerator.WriteHdr(ATag: Int32);
&Out.WriteByte($80);
end;
+procedure TBerGenerator.WriteHdr(AFlags, ATagNo: Int32);
+begin
+ TAsn1OutputStream.WriteIdentifier(&Out, AFlags, ATagNo);
+ &Out.WriteByte($80);
+end;
+
{ TBerSequenceGenerator }
constructor TBerSequenceGenerator.Create(AOutStream: TStream);
@@ -348,42 +354,18 @@ constructor TDerGenerator.Create(const AOutStream: TStream; ATagNo: Int32; AIsEx
class procedure TDerGenerator.WriteDerEncoded(const AOutStream: TStream; ATag: Int32; const ABytes: TCryptoLibByteArray);
begin
AOutStream.WriteByte(Byte(ATag));
- WriteLength(AOutStream, System.Length(ABytes));
+ TAsn1OutputStream.WriteDL(AOutStream, System.Length(ABytes));
if System.Length(ABytes) > 0 then
AOutStream.Write(ABytes[0], System.Length(ABytes));
end;
-class procedure TDerGenerator.WriteDerEncoded(const AOutStr: TStream; ATag: Int32; const AInStr: TStream);
+procedure TDerGenerator.WriteDerEncoded(const AOutStream: TStream; AFlags, ATagNo: Int32;
+ const ABytes: TCryptoLibByteArray);
begin
- WriteDerEncoded(AOutStr, ATag, TStreamUtilities.ReadAll(AInStr));
-end;
-
-class procedure TDerGenerator.WriteLength(const AOutStr: TStream; ALength: Int32);
-var
- LSize, LVal, LI: Int32;
-begin
- if ALength > 127 then
- begin
- LSize := 1;
- LVal := ALength;
- LVal := TBitOperations.Asr32(LVal, 8);
- while LVal <> 0 do
- begin
- System.Inc(LSize);
- LVal := TBitOperations.Asr32(LVal, 8);
- end;
- AOutStr.WriteByte(Byte(LSize or $80));
- LI := (LSize - 1) * 8;
- while LI >= 0 do
- begin
- AOutStr.WriteByte(Byte(TBitOperations.Asr32(ALength, LI)));
- System.Dec(LI, 8);
- end;
- end
- else
- begin
- AOutStr.WriteByte(Byte(ALength));
- end;
+ TAsn1OutputStream.WriteIdentifier(AOutStream, AFlags, ATagNo);
+ TAsn1OutputStream.WriteDL(AOutStream, System.Length(ABytes));
+ if System.Length(ABytes) > 0 then
+ AOutStream.Write(ABytes[0], System.Length(ABytes));
end;
procedure TDerGenerator.WriteDerEncoded(ATag: Int32; const ABytes: TCryptoLibByteArray);
@@ -407,7 +389,7 @@ procedure TDerGenerator.WriteDerEncoded(ATag: Int32; const ABytes: TCryptoLibByt
LBOut.Position := 0;
System.SetLength(LTemp, LBOut.Size);
LBOut.Read(LTemp[0], LBOut.Size);
- WriteDerEncoded(&Out, FTagNo or TAsn1Tags.ContextSpecific or TAsn1Tags.Constructed, LTemp);
+ WriteDerEncoded(&Out, TAsn1Tags.ContextSpecific or TAsn1Tags.Constructed, FTagNo, LTemp);
finally
LBOut.Free;
end;
@@ -419,7 +401,7 @@ procedure TDerGenerator.WriteDerEncoded(ATag: Int32; const ABytes: TCryptoLibByt
* if the base encoding is constructed, and shall be primitive otherwise; and b) the contents octets
* shall be [..] the contents octets of the base encoding.
}
- WriteDerEncoded(&Out, InheritConstructedFlag(FTagNo or TAsn1Tags.ContextSpecific, ATag), ABytes);
+ WriteDerEncoded(&Out, InheritConstructedFlag(TAsn1Tags.ContextSpecific, ATag), FTagNo, ABytes);
end;
end;
diff --git a/CryptoLib/src/Asn1/ClpAsn1Objects.pas b/CryptoLib/src/Asn1/ClpAsn1Objects.pas
index 8f577141..3b94366e 100644
--- a/CryptoLib/src/Asn1/ClpAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/ClpAsn1Objects.pas
@@ -127,6 +127,7 @@ Meta = class sealed(TAsn1UniversalType, IAsn1UniversalType)
constructor Create;
strict protected
function FromImplicitPrimitive(const AOctetString: IDerOctetString): IAsn1Object; override;
+ function FromImplicitConstructed(const ASequence: IAsn1Sequence): IAsn1Object; override;
public
class property Instance: IAsn1UniversalType read GetInstance;
end;
@@ -1597,7 +1598,7 @@ TDerExternal = class(TAsn1Object, IDerExternal)
FDataValueDescriptor: IAsn1ObjectDescriptor;
FEncoding: Int32;
FExternalContent: IAsn1Object;
-
+
function BuildSequence(): IAsn1Sequence; virtual;
function Asn1Equals(const AAsn1Object: IAsn1Object): Boolean; override;
@@ -2493,11 +2494,11 @@ Meta = class sealed(TAsn1UniversalType, IAsn1UniversalType)
///
/// Create from Int32 value.
///
- constructor Create(AValue: Int32); overload;
+ constructor Create(AValue: Int32); overload; deprecated 'Use ValueOf instead.';
///
/// Create from Int64 value.
///
- constructor Create(AValue: Int64); overload;
+ constructor Create(AValue: Int64); overload; deprecated 'Use ValueOf instead.';
///
/// Create from BigInteger value.
///
@@ -7238,17 +7239,17 @@ constructor TDerExternal.Create(const ASequence: IAsn1Sequence);
inherited Create();
if ASequence = nil then
raise EArgumentNilCryptoLibException.Create('sequence');
-
+
LOffset := 0;
LAsn1 := GetObjFromSequence(ASequence, LOffset);
-
+
if Supports(LAsn1, IDerObjectIdentifier, LDerObjectIdentifier) then
begin
FDirectReference := LDerObjectIdentifier;
System.Inc(LOffset);
LAsn1 := GetObjFromSequence(ASequence, LOffset);
end;
-
+
if Supports(LAsn1, IDerInteger, LDerInteger) then
begin
FIndirectReference := LDerInteger;
@@ -7268,13 +7269,13 @@ constructor TDerExternal.Create(const ASequence: IAsn1Sequence);
System.Inc(LOffset);
LAsn1 := GetObjFromSequence(ASequence, LOffset);
end;
-
+
if ASequence.Count <> LOffset + 1 then
raise EArgumentCryptoLibException.Create('input sequence too large');
-
+
if not Supports(LAsn1, IAsn1TaggedObject, LObj) then
raise EArgumentCryptoLibException.Create('No tagged object found in sequence. Structure doesn''t seem to be of type External');
-
+
FEncoding := CheckEncoding(LObj.TagNo);
FExternalContent := GetExternalContent(LObj);
end;
@@ -10166,7 +10167,7 @@ constructor TDerUtcTime.Create(const ATimeString: String);
constructor TDerUtcTime.Create(const ADateTime: TDateTime);
begin
- inherited Create(ADateTime);
+ inherited Create(ADateTime, TDateTimeUtilities.TwoDigitYearMax);
end;
constructor TDerUtcTime.Create(const ADateTime: TDateTime; ATwoDigitYearMax: Int32);
@@ -10259,7 +10260,7 @@ function TAsn1UtcTime.ToDateTime(ATwoDigitYearMax: Int32): TDateTime;
function TAsn1UtcTime.ToAdjustedDateTime: TDateTime;
begin
- Result := ToDateTime(2049);
+ Result := ToDateTime(TDateTimeUtilities.TwoDigitYearMax);
end;
class function TAsn1UtcTime.InRange(const ADateTime: TDateTime; ATwoDigitYearMax: Int32): Boolean;
@@ -12330,7 +12331,7 @@ class function TDerVisibleString.CreatePrimitive(const AContents: TCryptoLibByte
System.SetLength(FSmallConstants, 17);
for LI := 0 to System.Length(FSmallConstants) - 1 do
begin
- FSmallConstants[LI] := TDerInteger.Create(LI);
+ FSmallConstants[LI] := TDerInteger.Create(TCryptoLibByteArray.Create(Byte(LI)), False);
end;
FZero := FSmallConstants[0];
@@ -12530,7 +12531,7 @@ class function TDerInteger.ValueOf(AValue: Int32): IDerInteger;
if (AValue >= 0) and (AValue < System.Length(FSmallConstants)) then
Result := FSmallConstants[AValue]
else
- Result := TDerInteger.Create(AValue);
+ Result := TDerInteger.Create(TBigInteger.ValueOf(AValue));
end;
class function TDerInteger.ValueOf(AValue: Int64): IDerInteger;
@@ -12538,7 +12539,7 @@ class function TDerInteger.ValueOf(AValue: Int64): IDerInteger;
if (AValue >= 0) and (AValue < Int64(System.Length(FSmallConstants))) then
Result := FSmallConstants[Int32(AValue)]
else
- Result := TDerInteger.Create(AValue);
+ Result := TDerInteger.Create(TBigInteger.ValueOf(AValue));
end;
class function TDerInteger.GetInstance(const AObj: TObject): IDerInteger;
@@ -13101,7 +13102,12 @@ class function TAsn1OctetString.Meta.GetInstance: IAsn1UniversalType;
function TAsn1OctetString.Meta.FromImplicitPrimitive(const AOctetString: IDerOctetString): IAsn1Object;
begin
- Result := AOctetString as IAsn1Object;
+ Result := AOctetString;
+end;
+
+function TAsn1OctetString.Meta.FromImplicitConstructed(const ASequence: IAsn1Sequence): IAsn1Object;
+begin
+ Result := ASequence.ToAsn1OctetString();
end;
{ TAsn1Sequence.Meta }
@@ -13120,7 +13126,7 @@ class function TAsn1Sequence.Meta.GetInstance: IAsn1UniversalType;
function TAsn1Sequence.Meta.FromImplicitConstructed(const ASequence: IAsn1Sequence): IAsn1Object;
begin
- Result := ASequence as IAsn1Object;
+ Result := ASequence;
end;
{ TAsn1Set.Meta }
@@ -13267,7 +13273,7 @@ function TDerBitString.Meta.FromImplicitConstructed(const ASequence: IAsn1Sequen
LBitString: IDerBitString;
begin
LBitString := ASequence.ToAsn1BitString();
- Result := LBitString as IAsn1Object;
+ Result := LBitString;
end;
{ TAsn1GeneralizedTime.Meta }
@@ -13354,7 +13360,7 @@ function TDerExternal.Meta.FromImplicitConstructed(const ASequence: IAsn1Sequenc
LExternal: IDerExternal;
begin
LExternal := ASequence.ToAsn1External();
- Result := LExternal as IAsn1Object;
+ Result := LExternal;
end;
{ TDerUtf8String.Meta }
diff --git a/CryptoLib/src/Asn1/ClpAsn1Streams.pas b/CryptoLib/src/Asn1/ClpAsn1Streams.pas
index 714ad3f0..c8c56164 100644
--- a/CryptoLib/src/Asn1/ClpAsn1Streams.pas
+++ b/CryptoLib/src/Asn1/ClpAsn1Streams.pas
@@ -202,12 +202,22 @@ TAsn1OutputStream = class(TFilterStream)
///
/// Write a definite length value.
///
- procedure WriteDL(ADl: Int32);
+ procedure WriteDL(ADl: Int32); overload;
///
/// Write an identifier with flags and tag number.
///
- procedure WriteIdentifier(AFlags, ATagNo: Int32);
+ procedure WriteIdentifier(AFlags, ATagNo: Int32); overload;
+
+ ///
+ /// Write a definite length value to a stream.
+ ///
+ class procedure WriteDL(const AOutput: TStream; ADl: Int32); overload; static;
+
+ ///
+ /// Write an identifier with flags and tag number to a stream.
+ ///
+ class procedure WriteIdentifier(const AOutput: TStream; AFlags, ATagNo: Int32); overload; static;
///
/// Get encoding type from string.
@@ -895,13 +905,23 @@ procedure TAsn1OutputStream.EncodeContents(const AContentsEncodings
end;
procedure TAsn1OutputStream.WriteDL(ADl: Int32);
+begin
+ WriteDL(Self, ADl);
+end;
+
+procedure TAsn1OutputStream.WriteIdentifier(AFlags, ATagNo: Int32);
+begin
+ WriteIdentifier(Self, AFlags, ATagNo);
+end;
+
+class procedure TAsn1OutputStream.WriteDL(const AOutput: TStream; ADl: Int32);
var
LStack: TCryptoLibByteArray;
LPos, LCount: Int32;
begin
if ADl < 128 then
begin
- WriteByte(Byte(ADl));
+ AOutput.WriteByte(Byte(ADl));
Exit;
end;
@@ -918,17 +938,17 @@ procedure TAsn1OutputStream.WriteDL(ADl: Int32);
System.Dec(LPos);
LStack[LPos] := Byte($80 or LCount);
- Write(LStack[LPos], LCount + 1);
+ AOutput.Write(LStack[LPos], LCount + 1);
end;
-procedure TAsn1OutputStream.WriteIdentifier(AFlags, ATagNo: Int32);
+class procedure TAsn1OutputStream.WriteIdentifier(const AOutput: TStream; AFlags, ATagNo: Int32);
var
LStack: TCryptoLibByteArray;
LPos: Int32;
begin
if ATagNo < 31 then
begin
- WriteByte(Byte(AFlags or ATagNo));
+ AOutput.WriteByte(Byte(AFlags or ATagNo));
Exit;
end;
@@ -947,7 +967,7 @@ procedure TAsn1OutputStream.WriteIdentifier(AFlags, ATagNo: Int32);
System.Dec(LPos);
LStack[LPos] := Byte(AFlags or $1F);
- Write(LStack[LPos], System.Length(LStack) - LPos);
+ AOutput.Write(LStack[LPos], System.Length(LStack) - LPos);
end;
class function TAsn1OutputStream.GetEncodingType(const AEncoding: String): Int32;
diff --git a/CryptoLib/src/Asn1/Cms/ClpCmsObjectIdentifiers.pas b/CryptoLib/src/Asn1/Cms/ClpCmsObjectIdentifiers.pas
index daafc86d..e9735b68 100644
--- a/CryptoLib/src/Asn1/Cms/ClpCmsObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Cms/ClpCmsObjectIdentifiers.pas
@@ -78,9 +78,7 @@ TCmsObjectIdentifiers = class sealed(TObject)
class function GetIdOri: IDerObjectIdentifier; static; inline;
class function GetIdOriKem: IDerObjectIdentifier; static; inline;
class function GetIdAlgCekHkdfSha256: IDerObjectIdentifier; static; inline;
-
- class procedure Boot(); static;
- class constructor CmsObjectIdentifiers();
+ class constructor Create();
public
class property Data: IDerObjectIdentifier read GetData;
@@ -115,7 +113,7 @@ TCmsObjectIdentifiers = class sealed(TObject)
implementation
-class procedure TCmsObjectIdentifiers.Boot;
+class constructor TCmsObjectIdentifiers.Create;
begin
FData := TPkcsObjectIdentifiers.Data;
FSignedData := TPkcsObjectIdentifiers.SignedData;
@@ -145,11 +143,6 @@ class procedure TCmsObjectIdentifiers.Boot;
FIdAlgCekHkdfSha256 := TPkcsObjectIdentifiers.SmimeAlg.Branch('31');
end;
-class constructor TCmsObjectIdentifiers.CmsObjectIdentifiers;
-begin
- TCmsObjectIdentifiers.Boot();
-end;
-
class function TCmsObjectIdentifiers.GetData: IDerObjectIdentifier;
begin
Result := FData;
diff --git a/CryptoLib/src/Asn1/CryptLib/ClpCryptLibObjectIdentifiers.pas b/CryptoLib/src/Asn1/CryptLib/ClpCryptLibObjectIdentifiers.pas
index 64447c29..9ee3049f 100644
--- a/CryptoLib/src/Asn1/CryptLib/ClpCryptLibObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/CryptLib/ClpCryptLibObjectIdentifiers.pas
@@ -28,7 +28,6 @@ interface
TCryptLibObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FCryptlib, FEcc, FCurvey25519: IDerObjectIdentifier;
class function GetCryptlib: IDerObjectIdentifier; static; inline;
@@ -40,8 +39,6 @@ TCryptLibObjectIdentifiers = class abstract(TObject)
class property Cryptlib: IDerObjectIdentifier read GetCryptlib;
class property Ecc: IDerObjectIdentifier read GetEcc;
class property Curvey25519: IDerObjectIdentifier read GetCurvey25519;
-
- class procedure Boot; static;
end;
implementation
@@ -50,19 +47,9 @@ implementation
class constructor TCryptLibObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TCryptLibObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FCryptlib := TDerObjectIdentifier.Create('1.3.6.1.4.1.3029');
- FEcc := FCryptlib.Branch('1.5');
- FCurvey25519 := FEcc.Branch('1');
-
- FIsBooted := True;
- end;
+ FCryptlib := TDerObjectIdentifier.Create('1.3.6.1.4.1.3029');
+ FEcc := FCryptlib.Branch('1.5');
+ FCurvey25519 := FEcc.Branch('1');
end;
class function TCryptLibObjectIdentifiers.GetCryptlib: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/CryptoPro/ClpCryptoProObjectIdentifiers.pas b/CryptoLib/src/Asn1/CryptoPro/ClpCryptoProObjectIdentifiers.pas
index 457e3015..76059bc2 100644
--- a/CryptoLib/src/Asn1/CryptoPro/ClpCryptoProObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/CryptoPro/ClpCryptoProObjectIdentifiers.pas
@@ -29,7 +29,6 @@ interface
TCryptoProObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FGostId, FGostR3411, FGostR3411Hmac, FIdGost28147_89NoneKeyWrap,
FIdGost28147_89CryptoProKeyWrap, FGostR28147Gcfb,
FIdGost28147_89CryptoProTestParamSet, FIdGost28147_89CryptoProAParamSet,
@@ -107,8 +106,6 @@ TCryptoProObjectIdentifiers = class abstract(TObject)
class property GostR3410x2001CryptoProXchB: IDerObjectIdentifier read GetGostR3410x2001CryptoProXchB;
class property GostR3410x2001CryptoProESDH: IDerObjectIdentifier read GetGostR3410x2001CryptoProESDH;
class property GostR3410x2001DH: IDerObjectIdentifier read GetGostR3410x2001DH;
-
- class procedure Boot; static;
end;
implementation
@@ -117,46 +114,36 @@ implementation
class constructor TCryptoProObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TCryptoProObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FGostId := TDerObjectIdentifier.Create('1.2.643.2.2');
- FGostR3411 := FGostId.Branch('9');
- FGostR3411Hmac := FGostId.Branch('10');
- FIdGost28147_89NoneKeyWrap := FGostId.Branch('13.0');
- FIdGost28147_89CryptoProKeyWrap := FGostId.Branch('13.1');
- FGostR28147Gcfb := FGostId.Branch('21');
- FIdGost28147_89CryptoProTestParamSet := FGostId.Branch('31.0');
- FIdGost28147_89CryptoProAParamSet := FGostId.Branch('31.1');
- FIdGost28147_89CryptoProBParamSet := FGostId.Branch('31.2');
- FIdGost28147_89CryptoProCParamSet := FGostId.Branch('31.3');
- FIdGost28147_89CryptoProDParamSet := FGostId.Branch('31.4');
- FGostR3410x94 := FGostId.Branch('20');
- FGostR3410x2001 := FGostId.Branch('19');
- FGostR3411x94WithGostR3410x94 := FGostId.Branch('4');
- FGostR3411x94WithGostR3410x2001 := FGostId.Branch('3');
- FGostR3411x94CryptoProParamSet := FGostId.Branch('30.1');
- FGostR3410x94CryptoProA := FGostId.Branch('32.2');
- FGostR3410x94CryptoProB := FGostId.Branch('32.3');
- FGostR3410x94CryptoProC := FGostId.Branch('32.4');
- FGostR3410x94CryptoProD := FGostId.Branch('32.5');
- FGostR3410x94CryptoProXchA := FGostId.Branch('33.1');
- FGostR3410x94CryptoProXchB := FGostId.Branch('33.2');
- FGostR3410x94CryptoProXchC := FGostId.Branch('33.3');
- FGostR3410x2001CryptoProA := FGostId.Branch('35.1');
- FGostR3410x2001CryptoProB := FGostId.Branch('35.2');
- FGostR3410x2001CryptoProC := FGostId.Branch('35.3');
- FGostR3410x2001CryptoProXchA := FGostId.Branch('36.0');
- FGostR3410x2001CryptoProXchB := FGostId.Branch('36.1');
- FGostR3410x2001CryptoProESDH := FGostId.Branch('96');
- FGostR3410x2001DH := FGostId.Branch('98');
-
- FIsBooted := True;
- end;
+ FGostId := TDerObjectIdentifier.Create('1.2.643.2.2');
+ FGostR3411 := FGostId.Branch('9');
+ FGostR3411Hmac := FGostId.Branch('10');
+ FIdGost28147_89NoneKeyWrap := FGostId.Branch('13.0');
+ FIdGost28147_89CryptoProKeyWrap := FGostId.Branch('13.1');
+ FGostR28147Gcfb := FGostId.Branch('21');
+ FIdGost28147_89CryptoProTestParamSet := FGostId.Branch('31.0');
+ FIdGost28147_89CryptoProAParamSet := FGostId.Branch('31.1');
+ FIdGost28147_89CryptoProBParamSet := FGostId.Branch('31.2');
+ FIdGost28147_89CryptoProCParamSet := FGostId.Branch('31.3');
+ FIdGost28147_89CryptoProDParamSet := FGostId.Branch('31.4');
+ FGostR3410x94 := FGostId.Branch('20');
+ FGostR3410x2001 := FGostId.Branch('19');
+ FGostR3411x94WithGostR3410x94 := FGostId.Branch('4');
+ FGostR3411x94WithGostR3410x2001 := FGostId.Branch('3');
+ FGostR3411x94CryptoProParamSet := FGostId.Branch('30.1');
+ FGostR3410x94CryptoProA := FGostId.Branch('32.2');
+ FGostR3410x94CryptoProB := FGostId.Branch('32.3');
+ FGostR3410x94CryptoProC := FGostId.Branch('32.4');
+ FGostR3410x94CryptoProD := FGostId.Branch('32.5');
+ FGostR3410x94CryptoProXchA := FGostId.Branch('33.1');
+ FGostR3410x94CryptoProXchB := FGostId.Branch('33.2');
+ FGostR3410x94CryptoProXchC := FGostId.Branch('33.3');
+ FGostR3410x2001CryptoProA := FGostId.Branch('35.1');
+ FGostR3410x2001CryptoProB := FGostId.Branch('35.2');
+ FGostR3410x2001CryptoProC := FGostId.Branch('35.3');
+ FGostR3410x2001CryptoProXchA := FGostId.Branch('36.0');
+ FGostR3410x2001CryptoProXchB := FGostId.Branch('36.1');
+ FGostR3410x2001CryptoProESDH := FGostId.Branch('96');
+ FGostR3410x2001DH := FGostId.Branch('98');
end;
class function TCryptoProObjectIdentifiers.GetGostId: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/CryptoPro/ClpECGost3410NamedCurves.pas b/CryptoLib/src/Asn1/CryptoPro/ClpECGost3410NamedCurves.pas
index 3b8000cb..b0b12abf 100644
--- a/CryptoLib/src/Asn1/CryptoPro/ClpECGost3410NamedCurves.pas
+++ b/CryptoLib/src/Asn1/CryptoPro/ClpECGost3410NamedCurves.pas
@@ -57,9 +57,7 @@ TECGost3410NamedCurves = class sealed(TObject)
class procedure DefineCurve(const AName: String;
const AOid: IDerObjectIdentifier;
const AHolder: IX9ECParametersHolder); static;
-
- class procedure Boot; static;
- class constructor CreateECGost3410NamedCurves;
+ class constructor Create;
class destructor DestroyECGost3410NamedCurves;
public
@@ -166,7 +164,7 @@ class procedure TECGost3410NamedCurves.DefineCurve(const AName: String;
FObjIds.Add(LName, AOid);
end;
-class procedure TECGost3410NamedCurves.Boot;
+class constructor TECGost3410NamedCurves.Create;
begin
FObjIds := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FCurves := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
@@ -186,11 +184,6 @@ class procedure TECGost3410NamedCurves.Boot;
DefineCurve('Tc26-Gost-3410-12-512-paramSetC', TRosstandartObjectIdentifiers.IdTc26Gost3410_12_512ParamSetC, THolderIdTc26Gost341012512ParamSetC.Instance);
end;
-class constructor TECGost3410NamedCurves.CreateECGost3410NamedCurves;
-begin
- Boot;
-end;
-
class destructor TECGost3410NamedCurves.DestroyECGost3410NamedCurves;
begin
FObjIds.Free;
diff --git a/CryptoLib/src/Asn1/Eac/ClpEacObjectIdentifiers.pas b/CryptoLib/src/Asn1/Eac/ClpEacObjectIdentifiers.pas
index 460951b2..5d27412f 100644
--- a/CryptoLib/src/Asn1/Eac/ClpEacObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Eac/ClpEacObjectIdentifiers.pas
@@ -28,7 +28,6 @@ interface
TEacObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FBsiDe, FIdPK, FIdPKDH, FIdPKECDH, FIdCA, FIdCADH, FIdCADH3DesCbcCbc,
FIdCAECDH, FIdCAECDH3DesCbcCbc, FIdTA, FIdTARsa, FIdTARsaV1_5Sha1,
FIdTARsaV1_5Sha256, FIdTARsaPssSha1, FIdTARsaPssSha256, FIdTAEcdsa,
@@ -84,8 +83,6 @@ TEacObjectIdentifiers = class abstract(TObject)
class property IdTAEcdsaSha256: IDerObjectIdentifier read GetIdTAEcdsaSha256;
class property IdTAEcdsaSha384: IDerObjectIdentifier read GetIdTAEcdsaSha384;
class property IdTAEcdsaSha512: IDerObjectIdentifier read GetIdTAEcdsaSha512;
-
- class procedure Boot; static;
end;
implementation
@@ -94,38 +91,27 @@ implementation
class constructor TEacObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TEacObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- TBsiObjectIdentifiers.Boot;
- FBsiDe := TBsiObjectIdentifiers.BsiDe;
- FIdPK := FBsiDe.Branch('2.2.1');
- FIdPKDH := FIdPK.Branch('1');
- FIdPKECDH := FIdPK.Branch('2');
- FIdCA := FBsiDe.Branch('2.2.3');
- FIdCADH := FIdCA.Branch('1');
- FIdCADH3DesCbcCbc := FIdCADH.Branch('1');
- FIdCAECDH := FIdCA.Branch('2');
- FIdCAECDH3DesCbcCbc := FIdCAECDH.Branch('1');
- FIdTA := FBsiDe.Branch('2.2.2');
- FIdTARsa := FIdTA.Branch('1');
- FIdTARsaV1_5Sha1 := FIdTARsa.Branch('1');
- FIdTARsaV1_5Sha256 := FIdTARsa.Branch('2');
- FIdTARsaPssSha1 := FIdTARsa.Branch('3');
- FIdTARsaPssSha256 := FIdTARsa.Branch('4');
- FIdTAEcdsa := FIdTA.Branch('2');
- FIdTAEcdsaSha1 := FIdTAEcdsa.Branch('1');
- FIdTAEcdsaSha224 := FIdTAEcdsa.Branch('2');
- FIdTAEcdsaSha256 := FIdTAEcdsa.Branch('3');
- FIdTAEcdsaSha384 := FIdTAEcdsa.Branch('4');
- FIdTAEcdsaSha512 := FIdTAEcdsa.Branch('5');
-
- FIsBooted := True;
- end;
+ FBsiDe := TBsiObjectIdentifiers.BsiDe;
+ FIdPK := FBsiDe.Branch('2.2.1');
+ FIdPKDH := FIdPK.Branch('1');
+ FIdPKECDH := FIdPK.Branch('2');
+ FIdCA := FBsiDe.Branch('2.2.3');
+ FIdCADH := FIdCA.Branch('1');
+ FIdCADH3DesCbcCbc := FIdCADH.Branch('1');
+ FIdCAECDH := FIdCA.Branch('2');
+ FIdCAECDH3DesCbcCbc := FIdCAECDH.Branch('1');
+ FIdTA := FBsiDe.Branch('2.2.2');
+ FIdTARsa := FIdTA.Branch('1');
+ FIdTARsaV1_5Sha1 := FIdTARsa.Branch('1');
+ FIdTARsaV1_5Sha256 := FIdTARsa.Branch('2');
+ FIdTARsaPssSha1 := FIdTARsa.Branch('3');
+ FIdTARsaPssSha256 := FIdTARsa.Branch('4');
+ FIdTAEcdsa := FIdTA.Branch('2');
+ FIdTAEcdsaSha1 := FIdTAEcdsa.Branch('1');
+ FIdTAEcdsaSha224 := FIdTAEcdsa.Branch('2');
+ FIdTAEcdsaSha256 := FIdTAEcdsa.Branch('3');
+ FIdTAEcdsaSha384 := FIdTAEcdsa.Branch('4');
+ FIdTAEcdsaSha512 := FIdTAEcdsa.Branch('5');
end;
class function TEacObjectIdentifiers.GetBsiDe: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Edec/ClpEdECObjectIdentifiers.pas b/CryptoLib/src/Asn1/Edec/ClpEdECObjectIdentifiers.pas
index 791858b2..d506f04c 100644
--- a/CryptoLib/src/Asn1/Edec/ClpEdECObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Edec/ClpEdECObjectIdentifiers.pas
@@ -29,7 +29,6 @@ interface
TEdECObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FIdEdwardsCurveAlgs, FIdX25519, FIdX448, FIdEd25519, FIdEd448: IDerObjectIdentifier;
class function GetIdEdwardsCurveAlgs: IDerObjectIdentifier; static; inline;
@@ -45,8 +44,6 @@ TEdECObjectIdentifiers = class abstract(TObject)
class property IdX448: IDerObjectIdentifier read GetIdX448;
class property IdEd25519: IDerObjectIdentifier read GetIdEd25519;
class property IdEd448: IDerObjectIdentifier read GetIdEd448;
-
- class procedure Boot; static;
end;
implementation
@@ -55,21 +52,11 @@ implementation
class constructor TEdECObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TEdECObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FIdEdwardsCurveAlgs := TDerObjectIdentifier.Create('1.3.101');
- FIdX25519 := FIdEdwardsCurveAlgs.Branch('110');
- FIdX448 := FIdEdwardsCurveAlgs.Branch('111');
- FIdEd25519 := FIdEdwardsCurveAlgs.Branch('112');
- FIdEd448 := FIdEdwardsCurveAlgs.Branch('113');
-
- FIsBooted := True;
- end;
+ FIdEdwardsCurveAlgs := TDerObjectIdentifier.Create('1.3.101');
+ FIdX25519 := FIdEdwardsCurveAlgs.Branch('110');
+ FIdX448 := FIdEdwardsCurveAlgs.Branch('111');
+ FIdEd25519 := FIdEdwardsCurveAlgs.Branch('112');
+ FIdEd448 := FIdEdwardsCurveAlgs.Branch('113');
end;
class function TEdECObjectIdentifiers.GetIdEd448: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Gnu/ClpGnuObjectIdentifiers.pas b/CryptoLib/src/Asn1/Gnu/ClpGnuObjectIdentifiers.pas
index 4b058d27..4a3e848f 100644
--- a/CryptoLib/src/Asn1/Gnu/ClpGnuObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Gnu/ClpGnuObjectIdentifiers.pas
@@ -29,7 +29,6 @@ interface
TGnuObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FGnu, FGnuPG, FNotation, FPkaAddress, FGnuRadar,
FDigestAlgorithm, FTiger192,
FEncryptionAlgorithm, FSerpent,
@@ -117,8 +116,6 @@ TGnuObjectIdentifiers = class abstract(TObject)
class property EllipticCurve: IDerObjectIdentifier read GetEllipticCurve;
/// 1.3.6.1.4.1.11591.15.1 - Ed25519
class property Ed25519: IDerObjectIdentifier read GetEd25519;
-
- class procedure Boot; static;
end;
implementation
@@ -127,41 +124,31 @@ implementation
class constructor TGnuObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TGnuObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FGnu := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.1');
- FGnuPG := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.2');
- FNotation := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.2.1');
- FPkaAddress := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.2.1.1');
- FGnuRadar := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.3');
- FDigestAlgorithm := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.12');
- FTiger192 := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.12.2');
- FEncryptionAlgorithm := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13');
- FSerpent := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2');
- FSerpent128Ecb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.1');
- FSerpent128Cbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.2');
- FSerpent128Ofb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.3');
- FSerpent128Cfb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.4');
- FSerpent192Ecb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.21');
- FSerpent192Cbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.22');
- FSerpent192Ofb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.23');
- FSerpent192Cfb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.24');
- FSerpent256Ecb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.41');
- FSerpent256Cbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.42');
- FSerpent256Ofb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.43');
- FSerpent256Cfb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.44');
- FCrc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.14');
- FCrc32 := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.14.1');
- FEllipticCurve := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.15');
- FEd25519 := FEllipticCurve.Branch('1');
-
- FIsBooted := True;
- end;
+ FGnu := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.1');
+ FGnuPG := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.2');
+ FNotation := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.2.1');
+ FPkaAddress := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.2.1.1');
+ FGnuRadar := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.3');
+ FDigestAlgorithm := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.12');
+ FTiger192 := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.12.2');
+ FEncryptionAlgorithm := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13');
+ FSerpent := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2');
+ FSerpent128Ecb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.1');
+ FSerpent128Cbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.2');
+ FSerpent128Ofb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.3');
+ FSerpent128Cfb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.4');
+ FSerpent192Ecb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.21');
+ FSerpent192Cbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.22');
+ FSerpent192Ofb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.23');
+ FSerpent192Cfb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.24');
+ FSerpent256Ecb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.41');
+ FSerpent256Cbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.42');
+ FSerpent256Ofb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.43');
+ FSerpent256Cfb := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.13.2.44');
+ FCrc := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.14');
+ FCrc32 := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.14.1');
+ FEllipticCurve := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.15');
+ FEd25519 := FEllipticCurve.Branch('1');
end;
class function TGnuObjectIdentifiers.GetGnu: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Iana/ClpIanaObjectIdentifiers.pas b/CryptoLib/src/Asn1/Iana/ClpIanaObjectIdentifiers.pas
index 4125dc13..b73c0a6b 100644
--- a/CryptoLib/src/Asn1/Iana/ClpIanaObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Iana/ClpIanaObjectIdentifiers.pas
@@ -29,7 +29,6 @@ interface
TIanaObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FInternet, FDirectory, FMgmt, FExperimental, FClsPrivate, FSecurity,
FSNMPv2, FMail, FSecurityMechanisms, FSecurityNametypes, FPkix, FIpsec,
FIsakmpOakley, FHmacMD5, FHmacSha1, FHmacTiger, FHmacRipeMD160: IDerObjectIdentifier;
@@ -71,8 +70,6 @@ TIanaObjectIdentifiers = class abstract(TObject)
class property HmacSha1: IDerObjectIdentifier read GetHmacSha1;
class property HmacTiger: IDerObjectIdentifier read GetHmacTiger;
class property HmacRipeMD160: IDerObjectIdentifier read GetHmacRipeMD160;
-
- class procedure Boot; static;
end;
implementation
@@ -81,33 +78,23 @@ implementation
class constructor TIanaObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TIanaObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FInternet := TDerObjectIdentifier.Create('1.3.6.1');
- FDirectory := FInternet.Branch('1');
- FMgmt := FInternet.Branch('2');
- FExperimental := FInternet.Branch('3');
- FClsPrivate := FInternet.Branch('4');
- FSecurity := FInternet.Branch('5');
- FSNMPv2 := FInternet.Branch('6');
- FMail := FInternet.Branch('7');
- FSecurityMechanisms := FSecurity.Branch('5');
- FSecurityNametypes := FSecurity.Branch('6');
- FPkix := FSecurityMechanisms.Branch('7');
- FIpsec := FSecurityMechanisms.Branch('8');
- FIsakmpOakley := FIpsec.Branch('1');
- FHmacMD5 := FIsakmpOakley.Branch('1');
- FHmacSha1 := FIsakmpOakley.Branch('2');
- FHmacTiger := FIsakmpOakley.Branch('3');
- FHmacRipeMD160 := FIsakmpOakley.Branch('4');
-
- FIsBooted := True;
- end;
+ FInternet := TDerObjectIdentifier.Create('1.3.6.1');
+ FDirectory := FInternet.Branch('1');
+ FMgmt := FInternet.Branch('2');
+ FExperimental := FInternet.Branch('3');
+ FClsPrivate := FInternet.Branch('4');
+ FSecurity := FInternet.Branch('5');
+ FSNMPv2 := FInternet.Branch('6');
+ FMail := FInternet.Branch('7');
+ FSecurityMechanisms := FSecurity.Branch('5');
+ FSecurityNametypes := FSecurity.Branch('6');
+ FPkix := FSecurityMechanisms.Branch('7');
+ FIpsec := FSecurityMechanisms.Branch('8');
+ FIsakmpOakley := FIpsec.Branch('1');
+ FHmacMD5 := FIsakmpOakley.Branch('1');
+ FHmacSha1 := FIsakmpOakley.Branch('2');
+ FHmacTiger := FIsakmpOakley.Branch('3');
+ FHmacRipeMD160 := FIsakmpOakley.Branch('4');
end;
class function TIanaObjectIdentifiers.GetClsPrivate: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas b/CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas
index fb5cfe60..2947359c 100644
--- a/CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas
@@ -28,7 +28,6 @@ interface
TMiscObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FNetscape, FNetscapeCertType, FNetscapeBaseUrl, FNetscapeRevocationUrl,
FNetscapeCARevocationUrl, FNetscapeRenewalUrl, FNetscapeCAPolicyUrl,
FNetscapeSslServerName, FNetscapeCertComment, FVerisign,
@@ -133,8 +132,6 @@ TMiscObjectIdentifiers = class abstract(TObject)
class property IdAlgComposite: IDerObjectIdentifier read GetIdAlgComposite;
class property IdCompositeKey: IDerObjectIdentifier read GetIdCompositeKey;
class property IdOraclePkcs12TrustedKeyUsage: IDerObjectIdentifier read GetIdOraclePkcs12TrustedKeyUsage;
-
- class procedure Boot; static;
end;
implementation
@@ -143,67 +140,57 @@ implementation
class constructor TMiscObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TMiscObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FNetscape := TDerObjectIdentifier.Create('2.16.840.1.113730.1');
- FNetscapeCertType := FNetscape.Branch('1');
- FNetscapeBaseUrl := FNetscape.Branch('2');
- FNetscapeRevocationUrl := FNetscape.Branch('3');
- FNetscapeCARevocationUrl := FNetscape.Branch('4');
- FNetscapeRenewalUrl := FNetscape.Branch('7');
- FNetscapeCAPolicyUrl := FNetscape.Branch('8');
- FNetscapeSslServerName := FNetscape.Branch('12');
- FNetscapeCertComment := FNetscape.Branch('13');
-
- FVerisign := TDerObjectIdentifier.Create('2.16.840.1.113733.1');
- FVerisignCzagExtension := FVerisign.Branch('6.3');
- FVerisignPrivate_6_9 := FVerisign.Branch('6.9');
- FVerisignOnSiteJurisdictionHash := FVerisign.Branch('6.11');
- FVerisignBitString_6_13 := FVerisign.Branch('6.13');
- FVerisignDnbDunsNumber := FVerisign.Branch('6.15');
- FVerisignIssStrongCrypto := FVerisign.Branch('8.1');
-
- FNovell := TDerObjectIdentifier.Create('2.16.840.1.113719');
- FNovellSecurityAttribs := FNovell.Branch('1.9.4.1');
-
- FEntrust := TDerObjectIdentifier.Create('1.2.840.113533.7');
- FEntrustVersionExtension := FEntrust.Branch('65.0');
- FCast5Cbc := FEntrust.Branch('66.10');
-
- FHmacSha1 := TDerObjectIdentifier.Create('1.3.6.1.5.5.8.1.2');
- FAsSysSecAlgIdeaCbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.188.7.1.1.2');
-
- FCryptlib := TDerObjectIdentifier.Create('1.3.6.1.4.1.3029');
- FCryptlibAlgorithm := FCryptlib.Branch('1');
- FCryptlibAlgorithmBlowfishEcb := FCryptlibAlgorithm.Branch('1.1');
- FCryptlibAlgorithmBlowfishCbc := FCryptlibAlgorithm.Branch('1.2');
- FCryptlibAlgorithmBlowfishCfb := FCryptlibAlgorithm.Branch('1.3');
- FCryptlibAlgorithmBlowfishOfb := FCryptlibAlgorithm.Branch('1.4');
-
- FBlake2 := TDerObjectIdentifier.Create('1.3.6.1.4.1.1722.12.2');
- FIdBlake2b160 := FBlake2.Branch('1.5');
- FIdBlake2b256 := FBlake2.Branch('1.8');
- FIdBlake2b384 := FBlake2.Branch('1.12');
- FIdBlake2b512 := FBlake2.Branch('1.16');
- FIdBlake2s128 := FBlake2.Branch('2.4');
- FIdBlake2s160 := FBlake2.Branch('2.5');
- FIdBlake2s224 := FBlake2.Branch('2.7');
- FIdBlake2s256 := FBlake2.Branch('2.8');
- FBlake3 := FBlake2.Branch('3');
- FBlake3_256 := FBlake3.Branch('8');
-
- FIdScrypt := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.4.11');
- FIdAlgComposite := TDerObjectIdentifier.Create('1.3.6.1.4.1.18227.2.1');
- FIdCompositeKey := TDerObjectIdentifier.Create('2.16.840.1.114027.80.4.1');
- FIdOraclePkcs12TrustedKeyUsage := TDerObjectIdentifier.Create('2.16.840.1.113894.746875.1.1');
-
- FIsBooted := True;
- end;
+ FNetscape := TDerObjectIdentifier.Create('2.16.840.1.113730.1');
+ FNetscapeCertType := FNetscape.Branch('1');
+ FNetscapeBaseUrl := FNetscape.Branch('2');
+ FNetscapeRevocationUrl := FNetscape.Branch('3');
+ FNetscapeCARevocationUrl := FNetscape.Branch('4');
+ FNetscapeRenewalUrl := FNetscape.Branch('7');
+ FNetscapeCAPolicyUrl := FNetscape.Branch('8');
+ FNetscapeSslServerName := FNetscape.Branch('12');
+ FNetscapeCertComment := FNetscape.Branch('13');
+
+ FVerisign := TDerObjectIdentifier.Create('2.16.840.1.113733.1');
+ FVerisignCzagExtension := FVerisign.Branch('6.3');
+ FVerisignPrivate_6_9 := FVerisign.Branch('6.9');
+ FVerisignOnSiteJurisdictionHash := FVerisign.Branch('6.11');
+ FVerisignBitString_6_13 := FVerisign.Branch('6.13');
+ FVerisignDnbDunsNumber := FVerisign.Branch('6.15');
+ FVerisignIssStrongCrypto := FVerisign.Branch('8.1');
+
+ FNovell := TDerObjectIdentifier.Create('2.16.840.1.113719');
+ FNovellSecurityAttribs := FNovell.Branch('1.9.4.1');
+
+ FEntrust := TDerObjectIdentifier.Create('1.2.840.113533.7');
+ FEntrustVersionExtension := FEntrust.Branch('65.0');
+ FCast5Cbc := FEntrust.Branch('66.10');
+
+ FHmacSha1 := TDerObjectIdentifier.Create('1.3.6.1.5.5.8.1.2');
+ FAsSysSecAlgIdeaCbc := TDerObjectIdentifier.Create('1.3.6.1.4.1.188.7.1.1.2');
+
+ FCryptlib := TDerObjectIdentifier.Create('1.3.6.1.4.1.3029');
+ FCryptlibAlgorithm := FCryptlib.Branch('1');
+ FCryptlibAlgorithmBlowfishEcb := FCryptlibAlgorithm.Branch('1.1');
+ FCryptlibAlgorithmBlowfishCbc := FCryptlibAlgorithm.Branch('1.2');
+ FCryptlibAlgorithmBlowfishCfb := FCryptlibAlgorithm.Branch('1.3');
+ FCryptlibAlgorithmBlowfishOfb := FCryptlibAlgorithm.Branch('1.4');
+
+ FBlake2 := TDerObjectIdentifier.Create('1.3.6.1.4.1.1722.12.2');
+ FIdBlake2b160 := FBlake2.Branch('1.5');
+ FIdBlake2b256 := FBlake2.Branch('1.8');
+ FIdBlake2b384 := FBlake2.Branch('1.12');
+ FIdBlake2b512 := FBlake2.Branch('1.16');
+ FIdBlake2s128 := FBlake2.Branch('2.4');
+ FIdBlake2s160 := FBlake2.Branch('2.5');
+ FIdBlake2s224 := FBlake2.Branch('2.7');
+ FIdBlake2s256 := FBlake2.Branch('2.8');
+ FBlake3 := FBlake2.Branch('3');
+ FBlake3_256 := FBlake3.Branch('8');
+
+ FIdScrypt := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.4.11');
+ FIdAlgComposite := TDerObjectIdentifier.Create('1.3.6.1.4.1.18227.2.1');
+ FIdCompositeKey := TDerObjectIdentifier.Create('2.16.840.1.114027.80.4.1');
+ FIdOraclePkcs12TrustedKeyUsage := TDerObjectIdentifier.Create('2.16.840.1.113894.746875.1.1');
end;
class function TMiscObjectIdentifiers.GetAsSysSecAlgIdeaCbc: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Nist/ClpNistNamedCurves.pas b/CryptoLib/src/Asn1/Nist/ClpNistNamedCurves.pas
index 6990b843..fa736b9b 100644
--- a/CryptoLib/src/Asn1/Nist/ClpNistNamedCurves.pas
+++ b/CryptoLib/src/Asn1/Nist/ClpNistNamedCurves.pas
@@ -43,10 +43,8 @@ TNistNamedCurves = class sealed(TObject)
class function GetNames: TCryptoLibStringArray; static; inline;
class procedure DefineCurveAlias(const AName: String;
const AOid: IDerObjectIdentifier); static;
-
- class procedure Boot; static;
- class constructor CreateNistNamedCurves;
- class destructor DestroyNistNamedCurves;
+ class constructor Create;
+ class destructor Destroy;
public
class function GetByName(const AName: String): IX9ECParameters;
@@ -81,7 +79,7 @@ class procedure TNistNamedCurves.DefineCurveAlias(const AName: String;
FObjIds.Add(LName, AOid);
end;
-class procedure TNistNamedCurves.Boot;
+class constructor TNistNamedCurves.Create;
begin
FObjIds := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FNames := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
@@ -105,12 +103,7 @@ class procedure TNistNamedCurves.Boot;
DefineCurveAlias('P-521', TSecObjectIdentifiers.SecP521r1);
end;
-class constructor TNistNamedCurves.CreateNistNamedCurves;
-begin
- Boot;
-end;
-
-class destructor TNistNamedCurves.DestroyNistNamedCurves;
+class destructor TNistNamedCurves.Destroy;
begin
FObjIds.Free;
FNames.Free;
diff --git a/CryptoLib/src/Asn1/Nist/ClpNistObjectIdentifiers.pas b/CryptoLib/src/Asn1/Nist/ClpNistObjectIdentifiers.pas
index 39db3a6b..e2cb1640 100644
--- a/CryptoLib/src/Asn1/Nist/ClpNistObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Nist/ClpNistObjectIdentifiers.pas
@@ -30,8 +30,6 @@ TNistObjectIdentifiers = class sealed(TObject)
strict private
class var
-
- FIsBooted: Boolean;
FNistAlgorithm, FHashAlgs, FSigAlgs, FIdSha256, FIdSha384, FIdSha512,
FIdSha224, FIdSha512_224, FIdSha512_256, FIdSha3_224, FIdSha3_256,
FIdSha3_384, FIdSha3_512, FIdShake128, FIdShake256, FIdShake128Len, FIdShake256Len, FIdHMacWithSha3_224,
@@ -119,7 +117,7 @@ TNistObjectIdentifiers = class sealed(TObject)
class function GetIdRsassaPkcs1V15WithSha3_384: IDerObjectIdentifier; static; inline;
class function GetIdRsassaPkcs1V15WithSha3_512: IDerObjectIdentifier; static; inline;
- class constructor NistObjectIdentifiers();
+ class constructor Create();
public
@@ -215,9 +213,6 @@ TNistObjectIdentifiers = class sealed(TObject)
read GetIdRsassaPkcs1V15WithSha3_384;
class property IdRsassaPkcs1V15WithSha3_512: IDerObjectIdentifier
read GetIdRsassaPkcs1V15WithSha3_512;
-
- class procedure Boot(); static;
-
end;
implementation
@@ -540,94 +535,83 @@ class function TNistObjectIdentifiers.GetSigAlgs: IDerObjectIdentifier;
Result := FSigAlgs;
end;
-class constructor TNistObjectIdentifiers.NistObjectIdentifiers;
-begin
- TNistObjectIdentifiers.Boot;
-end;
-
-class procedure TNistObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FNistAlgorithm := TDerObjectIdentifier.Create('2.16.840.1.101.3.4');
- FHashAlgs := NistAlgorithm.Branch('2');
-
- FIdSha256 := HashAlgs.Branch('1');
- FIdSha384 := HashAlgs.Branch('2');
- FIdSha512 := HashAlgs.Branch('3');
- FIdSha224 := HashAlgs.Branch('4');
- FIdSha512_224 := HashAlgs.Branch('5');
- FIdSha512_256 := HashAlgs.Branch('6');
- FIdSha3_224 := HashAlgs.Branch('7');
- FIdSha3_256 := HashAlgs.Branch('8');
- FIdSha3_384 := HashAlgs.Branch('9');
- FIdSha3_512 := HashAlgs.Branch('10');
- FIdShake128 := HashAlgs.Branch('11');
- FIdShake256 := HashAlgs.Branch('12');
- FIdShake128Len := HashAlgs.Branch('17');
- FIdShake256Len := HashAlgs.Branch('18');
- FIdHMacWithSha3_224 := HashAlgs.Branch('13');
- FIdHMacWithSha3_256 := HashAlgs.Branch('14');
- FIdHMacWithSha3_384 := HashAlgs.Branch('15');
- FIdHMacWithSha3_512 := HashAlgs.Branch('16');
-
- FAES := TDerObjectIdentifier.Create(NistAlgorithm.ID + '.1');
-
- FIdAES128Ecb := TDerObjectIdentifier.Create(AES.ID + '.1');
- FIdAes128Cbc := TDerObjectIdentifier.Create(AES.ID + '.2');
- FIdAes128Ofb := TDerObjectIdentifier.Create(AES.ID + '.3');
- FIdAes128Cfb := TDerObjectIdentifier.Create(AES.ID + '.4');
- FIdAes192Ecb := TDerObjectIdentifier.Create(AES.ID + '.21');
- FIdAes192Cbc := TDerObjectIdentifier.Create(AES.ID + '.22');
- FIdAes192Ofb := TDerObjectIdentifier.Create(AES.ID + '.23');
- FIdAes192Cfb := TDerObjectIdentifier.Create(AES.ID + '.24');
- FIdAes256Ecb := TDerObjectIdentifier.Create(AES.ID + '.41');
- FIdAes256Cbc := TDerObjectIdentifier.Create(AES.ID + '.42');
- FIdAes256Ofb := TDerObjectIdentifier.Create(AES.ID + '.43');
- FIdAes256Cfb := TDerObjectIdentifier.Create(AES.ID + '.44');
-
- FIdAes128Gcm := TDerObjectIdentifier.Create(AES.ID + '.6');
- FIdAes192Gcm := TDerObjectIdentifier.Create(AES.ID + '.26');
- FIdAes256Gcm := TDerObjectIdentifier.Create(AES.ID + '.46');
-
- FIdAes128Wrap := TDerObjectIdentifier.Create(AES.ID + '.5');
- FIdAes128WrapPad := TDerObjectIdentifier.Create(AES.ID + '.8');
- FIdAes192Wrap := TDerObjectIdentifier.Create(AES.ID + '.25');
- FIdAes192WrapPad := TDerObjectIdentifier.Create(AES.ID + '.28');
- FIdAes256Wrap := TDerObjectIdentifier.Create(AES.ID + '.45');
- FIdAes256WrapPad := TDerObjectIdentifier.Create(AES.ID + '.48');
-
- //
- // signatures
- //
- FSigAlgs := NistAlgorithm.Branch('3');
- FIdDsaWithSha2 := SigAlgs;
-
- FDsaWithSha224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.1');
- FDsaWithSha256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.2');
- FDsaWithSha384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.3');
- FDsaWithSha512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.4');
-
- FIdDsaWithSha3_224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.5');
- FIdDsaWithSha3_256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.6');
- FIdDsaWithSha3_384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.7');
- FIdDsaWithSha3_512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.8');
-
- // ECDSA with SHA-3
- FIdECDsaWithSha3_224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.9');
- FIdECDsaWithSha3_256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.10');
- FIdECDsaWithSha3_384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.11');
- FIdECDsaWithSha3_512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.12');
-
- // RSA PKCS #1 v1.5 Signature with SHA-3 family
- FIdRsassaPkcs1V15WithSha3_224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.13');
- FIdRsassaPkcs1V15WithSha3_256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.14');
- FIdRsassaPkcs1V15WithSha3_384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.15');
- FIdRsassaPkcs1V15WithSha3_512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.16');
-
- FIsBooted := True;
- end;
-
+class constructor TNistObjectIdentifiers.Create;
+begin
+ FNistAlgorithm := TDerObjectIdentifier.Create('2.16.840.1.101.3.4');
+ FHashAlgs := NistAlgorithm.Branch('2');
+
+ FIdSha256 := HashAlgs.Branch('1');
+ FIdSha384 := HashAlgs.Branch('2');
+ FIdSha512 := HashAlgs.Branch('3');
+ FIdSha224 := HashAlgs.Branch('4');
+ FIdSha512_224 := HashAlgs.Branch('5');
+ FIdSha512_256 := HashAlgs.Branch('6');
+ FIdSha3_224 := HashAlgs.Branch('7');
+ FIdSha3_256 := HashAlgs.Branch('8');
+ FIdSha3_384 := HashAlgs.Branch('9');
+ FIdSha3_512 := HashAlgs.Branch('10');
+ FIdShake128 := HashAlgs.Branch('11');
+ FIdShake256 := HashAlgs.Branch('12');
+ FIdShake128Len := HashAlgs.Branch('17');
+ FIdShake256Len := HashAlgs.Branch('18');
+ FIdHMacWithSha3_224 := HashAlgs.Branch('13');
+ FIdHMacWithSha3_256 := HashAlgs.Branch('14');
+ FIdHMacWithSha3_384 := HashAlgs.Branch('15');
+ FIdHMacWithSha3_512 := HashAlgs.Branch('16');
+
+ FAES := TDerObjectIdentifier.Create(NistAlgorithm.ID + '.1');
+
+ FIdAES128Ecb := TDerObjectIdentifier.Create(AES.ID + '.1');
+ FIdAes128Cbc := TDerObjectIdentifier.Create(AES.ID + '.2');
+ FIdAes128Ofb := TDerObjectIdentifier.Create(AES.ID + '.3');
+ FIdAes128Cfb := TDerObjectIdentifier.Create(AES.ID + '.4');
+ FIdAes192Ecb := TDerObjectIdentifier.Create(AES.ID + '.21');
+ FIdAes192Cbc := TDerObjectIdentifier.Create(AES.ID + '.22');
+ FIdAes192Ofb := TDerObjectIdentifier.Create(AES.ID + '.23');
+ FIdAes192Cfb := TDerObjectIdentifier.Create(AES.ID + '.24');
+ FIdAes256Ecb := TDerObjectIdentifier.Create(AES.ID + '.41');
+ FIdAes256Cbc := TDerObjectIdentifier.Create(AES.ID + '.42');
+ FIdAes256Ofb := TDerObjectIdentifier.Create(AES.ID + '.43');
+ FIdAes256Cfb := TDerObjectIdentifier.Create(AES.ID + '.44');
+
+ FIdAes128Gcm := TDerObjectIdentifier.Create(AES.ID + '.6');
+ FIdAes192Gcm := TDerObjectIdentifier.Create(AES.ID + '.26');
+ FIdAes256Gcm := TDerObjectIdentifier.Create(AES.ID + '.46');
+
+ FIdAes128Wrap := TDerObjectIdentifier.Create(AES.ID + '.5');
+ FIdAes128WrapPad := TDerObjectIdentifier.Create(AES.ID + '.8');
+ FIdAes192Wrap := TDerObjectIdentifier.Create(AES.ID + '.25');
+ FIdAes192WrapPad := TDerObjectIdentifier.Create(AES.ID + '.28');
+ FIdAes256Wrap := TDerObjectIdentifier.Create(AES.ID + '.45');
+ FIdAes256WrapPad := TDerObjectIdentifier.Create(AES.ID + '.48');
+
+ //
+ // signatures
+ //
+ FSigAlgs := NistAlgorithm.Branch('3');
+ FIdDsaWithSha2 := SigAlgs;
+
+ FDsaWithSha224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.1');
+ FDsaWithSha256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.2');
+ FDsaWithSha384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.3');
+ FDsaWithSha512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.4');
+
+ FIdDsaWithSha3_224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.5');
+ FIdDsaWithSha3_256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.6');
+ FIdDsaWithSha3_384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.7');
+ FIdDsaWithSha3_512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.8');
+
+ // ECDSA with SHA-3
+ FIdECDsaWithSha3_224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.9');
+ FIdECDsaWithSha3_256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.10');
+ FIdECDsaWithSha3_384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.11');
+ FIdECDsaWithSha3_512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.12');
+
+ // RSA PKCS #1 v1.5 Signature with SHA-3 family
+ FIdRsassaPkcs1V15WithSha3_224 := TDerObjectIdentifier.Create(SigAlgs.ID + '.13');
+ FIdRsassaPkcs1V15WithSha3_256 := TDerObjectIdentifier.Create(SigAlgs.ID + '.14');
+ FIdRsassaPkcs1V15WithSha3_384 := TDerObjectIdentifier.Create(SigAlgs.ID + '.15');
+ FIdRsassaPkcs1V15WithSha3_512 := TDerObjectIdentifier.Create(SigAlgs.ID + '.16');
end;
end.
diff --git a/CryptoLib/src/Asn1/Oiw/ClpOiwObjectIdentifiers.pas b/CryptoLib/src/Asn1/Oiw/ClpOiwObjectIdentifiers.pas
index ec1ff20e..f39ee8aa 100644
--- a/CryptoLib/src/Asn1/Oiw/ClpOiwObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Oiw/ClpOiwObjectIdentifiers.pas
@@ -28,7 +28,6 @@ interface
TOiwObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FMd4WithRsa, FMd5WithRsa, FMd4WithRsaEncryption, FDesEcb, FDesCbc, FDesOfb,
FDesCfb, FDesEde, FIdSha1, FDsaWithSha1, FSha1WithRsa: IDerObjectIdentifier;
@@ -58,8 +57,6 @@ TOiwObjectIdentifiers = class abstract(TObject)
class property IdSha1: IDerObjectIdentifier read GetIdSha1;
class property DsaWithSha1: IDerObjectIdentifier read GetDsaWithSha1;
class property Sha1WithRsa: IDerObjectIdentifier read GetSha1WithRsa;
-
- class procedure Boot; static;
end;
implementation
@@ -68,27 +65,17 @@ implementation
class constructor TOiwObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TOiwObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FMd4WithRsa := TDerObjectIdentifier.Create('1.3.14.3.2.2');
- FMd5WithRsa := TDerObjectIdentifier.Create('1.3.14.3.2.3');
- FMd4WithRsaEncryption := TDerObjectIdentifier.Create('1.3.14.3.2.4');
- FDesEcb := TDerObjectIdentifier.Create('1.3.14.3.2.6');
- FDesCbc := TDerObjectIdentifier.Create('1.3.14.3.2.7');
- FDesOfb := TDerObjectIdentifier.Create('1.3.14.3.2.8');
- FDesCfb := TDerObjectIdentifier.Create('1.3.14.3.2.9');
- FDesEde := TDerObjectIdentifier.Create('1.3.14.3.2.17');
- FIdSha1 := TDerObjectIdentifier.Create('1.3.14.3.2.26');
- FDsaWithSha1 := TDerObjectIdentifier.Create('1.3.14.3.2.27');
- FSha1WithRsa := TDerObjectIdentifier.Create('1.3.14.3.2.29');
-
- FIsBooted := True;
- end;
+ FMd4WithRsa := TDerObjectIdentifier.Create('1.3.14.3.2.2');
+ FMd5WithRsa := TDerObjectIdentifier.Create('1.3.14.3.2.3');
+ FMd4WithRsaEncryption := TDerObjectIdentifier.Create('1.3.14.3.2.4');
+ FDesEcb := TDerObjectIdentifier.Create('1.3.14.3.2.6');
+ FDesCbc := TDerObjectIdentifier.Create('1.3.14.3.2.7');
+ FDesOfb := TDerObjectIdentifier.Create('1.3.14.3.2.8');
+ FDesCfb := TDerObjectIdentifier.Create('1.3.14.3.2.9');
+ FDesEde := TDerObjectIdentifier.Create('1.3.14.3.2.17');
+ FIdSha1 := TDerObjectIdentifier.Create('1.3.14.3.2.26');
+ FDsaWithSha1 := TDerObjectIdentifier.Create('1.3.14.3.2.27');
+ FSha1WithRsa := TDerObjectIdentifier.Create('1.3.14.3.2.29');
end;
class function TOiwObjectIdentifiers.GetDesCbc: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Pkcs/ClpPkcsObjectIdentifiers.pas b/CryptoLib/src/Asn1/Pkcs/ClpPkcsObjectIdentifiers.pas
index 8e4f04e3..8abf709c 100644
--- a/CryptoLib/src/Asn1/Pkcs/ClpPkcsObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Pkcs/ClpPkcsObjectIdentifiers.pas
@@ -100,9 +100,6 @@ TPkcsObjectIdentifiers = class abstract(TObject)
CrlTypes: String = '1.2.840.113549.1.9.23';
class var
-
- FIsBooted: Boolean;
-
// PKCS#1 RSA OIDs
FRsaEncryption,
FMD2WithRsaEncryption,
@@ -343,7 +340,7 @@ TPkcsObjectIdentifiers = class abstract(TObject)
class function GetPbeWithShaAnd128BitRC2Cbc: IDerObjectIdentifier; static; inline;
class function GetPbewithShaAnd40BitRC2Cbc: IDerObjectIdentifier; static; inline;
- class constructor PkcsObjectIdentifiers();
+ class constructor Create();
public
@@ -524,181 +521,12 @@ TPkcsObjectIdentifiers = class abstract(TObject)
class property PbeWithShaAnd2KeyTripleDesCbc: IDerObjectIdentifier read GetPbeWithShaAnd2KeyTripleDesCbc;
class property PbeWithShaAnd128BitRC2Cbc: IDerObjectIdentifier read GetPbeWithShaAnd128BitRC2Cbc;
class property PbewithShaAnd40BitRC2Cbc: IDerObjectIdentifier read GetPbewithShaAnd40BitRC2Cbc;
-
- class procedure Boot(); static;
-
end;
implementation
{ TPkcsObjectIdentifiers }
-class procedure TPkcsObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- // PKCS#1 RSA
- FRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.1');
- FMD2WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.2');
- FMD4WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.3');
- FMD5WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.4');
- FSha1WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.5');
- FSrsaOaepEncryptionSet := TDerObjectIdentifier.Create(Pkcs1 + '.6');
- FIdRsaesOaep := TDerObjectIdentifier.Create(Pkcs1 + '.7');
- FIdMgf1 := TDerObjectIdentifier.Create(Pkcs1 + '.8');
- FIdPSpecified := TDerObjectIdentifier.Create(Pkcs1 + '.9');
- FIdRsassaPss := TDerObjectIdentifier.Create(Pkcs1 + '.10');
- FSha256WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.11');
- FSha384WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.12');
- FSha512WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.13');
- FSha224WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.14');
- FSha512_224WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.15');
- FSha512_256WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.16');
-
- // PKCS#3
- FDhKeyAgreement := TDerObjectIdentifier.Create(Pkcs3 + '.1');
-
- // PKCS#5
- FIdPbkdf2 := TDerObjectIdentifier.Create(Pkcs5 + '.12');
- FPbeWithMD2AndDesCbc := TDerObjectIdentifier.Create(Pkcs5 + '.1');
- FPbeWithMD2AndRC2Cbc := TDerObjectIdentifier.Create(Pkcs5 + '.4');
- FPbeWithMD5AndDesCbc := TDerObjectIdentifier.Create(Pkcs5 + '.3');
- FPbeWithMD5AndRC2Cbc := TDerObjectIdentifier.Create(Pkcs5 + '.6');
- FPbeWithSha1AndDesCbc := TDerObjectIdentifier.Create(Pkcs5 + '.10');
- FPbeWithSha1AndRC2Cbc := TDerObjectIdentifier.Create(Pkcs5 + '.11');
- FIdPbeS2 := TDerObjectIdentifier.Create(Pkcs5 + '.13');
- FIdPbmac1 := TDerObjectIdentifier.Create(Pkcs5 + '.14');
-
- // EncryptionAlgorithm
- FDesEde3Cbc := TDerObjectIdentifier.Create(EncryptionAlgorithm + '.7');
- FRC2Cbc := TDerObjectIdentifier.Create(EncryptionAlgorithm + '.2');
- Frc4 := TDerObjectIdentifier.Create(EncryptionAlgorithm + '.4');
-
- // PKCS#7
- FData := TDerObjectIdentifier.Create(Pkcs7 + '.1');
- FSignedData := TDerObjectIdentifier.Create(Pkcs7 + '.2');
- FEnvelopedData := TDerObjectIdentifier.Create(Pkcs7 + '.3');
- FSignedAndEnvelopedData := TDerObjectIdentifier.Create(Pkcs7 + '.4');
- FDigestedData := TDerObjectIdentifier.Create(Pkcs7 + '.5');
- FEncryptedData := TDerObjectIdentifier.Create(Pkcs7 + '.6');
-
- // Digest algorithms
- FMD2 := TDerObjectIdentifier.Create(DigestAlgorithm + '.2');
- FMD4 := TDerObjectIdentifier.Create(DigestAlgorithm + '.4');
- FMD5 := TDerObjectIdentifier.Create(DigestAlgorithm + '.5');
- FIdHmacWithSha1 := TDerObjectIdentifier.Create(DigestAlgorithm + '.7');
- FIdHmacWithSha224 := TDerObjectIdentifier.Create(DigestAlgorithm + '.8');
- FIdHmacWithSha256 := TDerObjectIdentifier.Create(DigestAlgorithm + '.9');
- FIdHmacWithSha384 := TDerObjectIdentifier.Create(DigestAlgorithm + '.10');
- FIdHmacWithSha512 := TDerObjectIdentifier.Create(DigestAlgorithm + '.11');
- FIdHmacWithSha512_224 := TDerObjectIdentifier.Create(DigestAlgorithm + '.12');
- FIdHmacWithSha512_256 := TDerObjectIdentifier.Create(DigestAlgorithm + '.13');
-
- // PKCS#9
- FPkcs9AtEmailAddress := TDerObjectIdentifier.Create(Pkcs9 + '.1');
- FPkcs9AtUnstructuredName := TDerObjectIdentifier.Create(Pkcs9 + '.2');
- FPkcs9AtContentType := TDerObjectIdentifier.Create(Pkcs9 + '.3');
- FPkcs9AtMessageDigest := TDerObjectIdentifier.Create(Pkcs9 + '.4');
- FPkcs9AtSigningTime := TDerObjectIdentifier.Create(Pkcs9 + '.5');
- FPkcs9AtCounterSignature := TDerObjectIdentifier.Create(Pkcs9 + '.6');
- FPkcs9AtChallengePassword := TDerObjectIdentifier.Create(Pkcs9 + '.7');
- FPkcs9AtUnstructuredAddress := TDerObjectIdentifier.Create(Pkcs9 + '.8');
- FPkcs9AtExtendedCertificateAttributes := TDerObjectIdentifier.Create(Pkcs9 + '.9');
- FPkcs9AtSigningDescription := TDerObjectIdentifier.Create(Pkcs9 + '.13');
- FPkcs9AtExtensionRequest := TDerObjectIdentifier.Create(Pkcs9 + '.14');
- FPkcs9AtSmimeCapabilities := TDerObjectIdentifier.Create(Pkcs9 + '.15');
- FIdSmime := TDerObjectIdentifier.Create(Pkcs9 + '.16');
- FPkcs9AtFriendlyName := TDerObjectIdentifier.Create(Pkcs9 + '.20');
- FPkcs9AtLocalKeyID := TDerObjectIdentifier.Create(Pkcs9 + '.21');
- FX509Certificate := TDerObjectIdentifier.Create(CertTypes + '.1');
- FSdsiCertificate := TDerObjectIdentifier.Create(CertTypes + '.2');
- FX509Crl := TDerObjectIdentifier.Create(CrlTypes + '.1');
- FSmimeAlg := FIdSmime.Branch('3');
- FIdAlg := FSmimeAlg;
- FIdAlgEsdh := FSmimeAlg.Branch('5');
- FIdAlgCms3DesWrap := FSmimeAlg.Branch('6');
- FIdAlgCmsRC2Wrap := FSmimeAlg.Branch('7');
- FIdAlgZlibCompress := FSmimeAlg.Branch('8');
- FIdAlgPwriKek := FSmimeAlg.Branch('9');
- FIdAlgSsdh := FSmimeAlg.Branch('10');
- FId_aa_cmsAlgorithmProtect := TDerObjectIdentifier.Create(Pkcs9 + '.52');
- FIdRsaKem := FSmimeAlg.Branch('14');
- FIdAlgHssLmsHashsig := FSmimeAlg.Branch('17');
- FIdAlgAeadChaCha20Poly1305 := FSmimeAlg.Branch('18');
- FDhSinglePassStdDHHkdfSha256Scheme := FSmimeAlg.Branch('19');
- FDhSinglePassStdDHHkdfSha384Scheme := FSmimeAlg.Branch('20');
- FDhSinglePassStdDHHkdfSha512Scheme := FSmimeAlg.Branch('21');
- FIdAlgHkdfWithSha256 := FSmimeAlg.Branch('28');
- FIdAlgHkdfWithSha384 := FSmimeAlg.Branch('29');
- FIdAlgHkdfWithSha512 := FSmimeAlg.Branch('30');
- FPreferSignedData := FPkcs9AtSmimeCapabilities.Branch('1');
- FCannotDecryptAny := FPkcs9AtSmimeCapabilities.Branch('2');
- FSmimeCapabilitiesVersions := FPkcs9AtSmimeCapabilities.Branch('3');
- FId_ct := FIdSmime.Branch('1');
- FIdCTAuthData := FId_ct.Branch('2');
- FIdCTTstInfo := FId_ct.Branch('4');
- FIdCTCompressedData := FId_ct.Branch('9');
- FIdCTAuthEnvelopedData := FId_ct.Branch('23');
- FIdCTTimestampedData := FId_ct.Branch('31');
- FId_cti := FIdSmime.Branch('6');
- FIdCtiEtsProofOfOrigin := FId_cti.Branch('1');
- FIdCtiEtsProofOfReceipt := FId_cti.Branch('2');
- FIdCtiEtsProofOfDelivery := FId_cti.Branch('3');
- FIdCtiEtsProofOfSender := FId_cti.Branch('4');
- FIdCtiEtsProofOfApproval := FId_cti.Branch('5');
- FIdCtiEtsProofOfCreation := FId_cti.Branch('6');
- FId_aa := FIdSmime.Branch('2');
- FIdAAOid := FId_aa;
- FPkcs9AtBinarySigningTime := FId_aa.Branch('46');
- FIdAAReceiptRequest := FId_aa.Branch('1');
- FIdAAContentHint := FId_aa.Branch('4');
- FIdAAMsgSigDigest := FId_aa.Branch('5');
- FIdAAContentReference := FId_aa.Branch('10');
- FIdAAEncrypKeyPref := FId_aa.Branch('11');
- FIdAASigningCertificate := FId_aa.Branch('12');
- FIdAAContentIdentifier := FId_aa.Branch('7');
- FIdAASignatureTimeStampToken := FId_aa.Branch('14');
- FIdAAEtsSigPolicyID := FId_aa.Branch('15');
- FIdAAEtsCommitmentType := FId_aa.Branch('16');
- FIdAAEtsSignerLocation := FId_aa.Branch('17');
- FIdAAEtsSignerAttr := FId_aa.Branch('18');
- FIdAAEtsOtherSigCert := FId_aa.Branch('19');
- FIdAAEtsContentTimestamp := FId_aa.Branch('20');
- FIdAAEtsCertificateRefs := FId_aa.Branch('21');
- FIdAAEtsRevocationRefs := FId_aa.Branch('22');
- FIdAAEtsCertValues := FId_aa.Branch('23');
- FIdAAEtsRevocationValues := FId_aa.Branch('24');
- FIdAAEtsEscTimeStamp := FId_aa.Branch('25');
- FIdAAEtsCertCrlTimestamp := FId_aa.Branch('26');
- FIdAAEtsArchiveTimestamp := FId_aa.Branch('27');
- FIdAADecryptKeyID := FId_aa.Branch('37');
- FIdAAImplCryptoAlgs := FId_aa.Branch('38');
- FIdAAAsymmDecryptKeyID := FId_aa.Branch('54');
- FIdAAImplCompressAlgs := FId_aa.Branch('43');
- FIdAACommunityIdentifiers := FId_aa.Branch('40');
- FIdAASigningCertificateV2 := FId_aa.Branch('47');
- FIdAAEtsArchiveTimestampV2 := FId_aa.Branch('48');
- FId_spq := FIdSmime.Branch('5');
- FIdSpqEtsUri := FId_spq.Branch('1');
- FIdSpqEtsUNotice := FId_spq.Branch('2');
- // PKCS#12
- FKeyBag := TDerObjectIdentifier.Create(BagTypes + '.1');
- FPkcs8ShroudedKeyBag := TDerObjectIdentifier.Create(BagTypes + '.2');
- FCertBag := TDerObjectIdentifier.Create(BagTypes + '.3');
- FCrlBag := TDerObjectIdentifier.Create(BagTypes + '.4');
- FSecretBag := TDerObjectIdentifier.Create(BagTypes + '.5');
- FSafeContentsBag := TDerObjectIdentifier.Create(BagTypes + '.6');
- FPbeWithShaAnd128BitRC4 := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.1');
- FPbeWithShaAnd40BitRC4 := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.2');
- FPbeWithShaAnd3KeyTripleDesCbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.3');
- FPbeWithShaAnd2KeyTripleDesCbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.4');
- FPbeWithShaAnd128BitRC2Cbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.5');
- FPbewithShaAnd40BitRC2Cbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.6');
-
- FIsBooted := True;
- end;
-end;
-
// PKCS#1 RSA getters
class function TPkcsObjectIdentifiers.GetRsaEncryption: IDerObjectIdentifier;
@@ -1428,9 +1256,165 @@ class function TPkcsObjectIdentifiers.GetPbewithShaAnd40BitRC2Cbc: IDerObjectIde
Result := FPbewithShaAnd40BitRC2Cbc;
end;
-class constructor TPkcsObjectIdentifiers.PkcsObjectIdentifiers;
-begin
- TPkcsObjectIdentifiers.Boot;
+class constructor TPkcsObjectIdentifiers.Create;
+begin
+ // PKCS#1 RSA
+ FRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.1');
+ FMD2WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.2');
+ FMD4WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.3');
+ FMD5WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.4');
+ FSha1WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.5');
+ FSrsaOaepEncryptionSet := TDerObjectIdentifier.Create(Pkcs1 + '.6');
+ FIdRsaesOaep := TDerObjectIdentifier.Create(Pkcs1 + '.7');
+ FIdMgf1 := TDerObjectIdentifier.Create(Pkcs1 + '.8');
+ FIdPSpecified := TDerObjectIdentifier.Create(Pkcs1 + '.9');
+ FIdRsassaPss := TDerObjectIdentifier.Create(Pkcs1 + '.10');
+ FSha256WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.11');
+ FSha384WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.12');
+ FSha512WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.13');
+ FSha224WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.14');
+ FSha512_224WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.15');
+ FSha512_256WithRsaEncryption := TDerObjectIdentifier.Create(Pkcs1 + '.16');
+
+ // PKCS#3
+ FDhKeyAgreement := TDerObjectIdentifier.Create(Pkcs3 + '.1');
+
+ // PKCS#5
+ FIdPbkdf2 := TDerObjectIdentifier.Create(Pkcs5 + '.12');
+ FPbeWithMD2AndDesCbc := TDerObjectIdentifier.Create(Pkcs5 + '.1');
+ FPbeWithMD2AndRC2Cbc := TDerObjectIdentifier.Create(Pkcs5 + '.4');
+ FPbeWithMD5AndDesCbc := TDerObjectIdentifier.Create(Pkcs5 + '.3');
+ FPbeWithMD5AndRC2Cbc := TDerObjectIdentifier.Create(Pkcs5 + '.6');
+ FPbeWithSha1AndDesCbc := TDerObjectIdentifier.Create(Pkcs5 + '.10');
+ FPbeWithSha1AndRC2Cbc := TDerObjectIdentifier.Create(Pkcs5 + '.11');
+ FIdPbeS2 := TDerObjectIdentifier.Create(Pkcs5 + '.13');
+ FIdPbmac1 := TDerObjectIdentifier.Create(Pkcs5 + '.14');
+
+ // EncryptionAlgorithm
+ FDesEde3Cbc := TDerObjectIdentifier.Create(EncryptionAlgorithm + '.7');
+ FRC2Cbc := TDerObjectIdentifier.Create(EncryptionAlgorithm + '.2');
+ Frc4 := TDerObjectIdentifier.Create(EncryptionAlgorithm + '.4');
+
+ // PKCS#7
+ FData := TDerObjectIdentifier.Create(Pkcs7 + '.1');
+ FSignedData := TDerObjectIdentifier.Create(Pkcs7 + '.2');
+ FEnvelopedData := TDerObjectIdentifier.Create(Pkcs7 + '.3');
+ FSignedAndEnvelopedData := TDerObjectIdentifier.Create(Pkcs7 + '.4');
+ FDigestedData := TDerObjectIdentifier.Create(Pkcs7 + '.5');
+ FEncryptedData := TDerObjectIdentifier.Create(Pkcs7 + '.6');
+
+ // Digest algorithms
+ FMD2 := TDerObjectIdentifier.Create(DigestAlgorithm + '.2');
+ FMD4 := TDerObjectIdentifier.Create(DigestAlgorithm + '.4');
+ FMD5 := TDerObjectIdentifier.Create(DigestAlgorithm + '.5');
+ FIdHmacWithSha1 := TDerObjectIdentifier.Create(DigestAlgorithm + '.7');
+ FIdHmacWithSha224 := TDerObjectIdentifier.Create(DigestAlgorithm + '.8');
+ FIdHmacWithSha256 := TDerObjectIdentifier.Create(DigestAlgorithm + '.9');
+ FIdHmacWithSha384 := TDerObjectIdentifier.Create(DigestAlgorithm + '.10');
+ FIdHmacWithSha512 := TDerObjectIdentifier.Create(DigestAlgorithm + '.11');
+ FIdHmacWithSha512_224 := TDerObjectIdentifier.Create(DigestAlgorithm + '.12');
+ FIdHmacWithSha512_256 := TDerObjectIdentifier.Create(DigestAlgorithm + '.13');
+
+ // PKCS#9
+ FPkcs9AtEmailAddress := TDerObjectIdentifier.Create(Pkcs9 + '.1');
+ FPkcs9AtUnstructuredName := TDerObjectIdentifier.Create(Pkcs9 + '.2');
+ FPkcs9AtContentType := TDerObjectIdentifier.Create(Pkcs9 + '.3');
+ FPkcs9AtMessageDigest := TDerObjectIdentifier.Create(Pkcs9 + '.4');
+ FPkcs9AtSigningTime := TDerObjectIdentifier.Create(Pkcs9 + '.5');
+ FPkcs9AtCounterSignature := TDerObjectIdentifier.Create(Pkcs9 + '.6');
+ FPkcs9AtChallengePassword := TDerObjectIdentifier.Create(Pkcs9 + '.7');
+ FPkcs9AtUnstructuredAddress := TDerObjectIdentifier.Create(Pkcs9 + '.8');
+ FPkcs9AtExtendedCertificateAttributes := TDerObjectIdentifier.Create(Pkcs9 + '.9');
+ FPkcs9AtSigningDescription := TDerObjectIdentifier.Create(Pkcs9 + '.13');
+ FPkcs9AtExtensionRequest := TDerObjectIdentifier.Create(Pkcs9 + '.14');
+ FPkcs9AtSmimeCapabilities := TDerObjectIdentifier.Create(Pkcs9 + '.15');
+ FIdSmime := TDerObjectIdentifier.Create(Pkcs9 + '.16');
+ FPkcs9AtFriendlyName := TDerObjectIdentifier.Create(Pkcs9 + '.20');
+ FPkcs9AtLocalKeyID := TDerObjectIdentifier.Create(Pkcs9 + '.21');
+ FX509Certificate := TDerObjectIdentifier.Create(CertTypes + '.1');
+ FSdsiCertificate := TDerObjectIdentifier.Create(CertTypes + '.2');
+ FX509Crl := TDerObjectIdentifier.Create(CrlTypes + '.1');
+ FSmimeAlg := FIdSmime.Branch('3');
+ FIdAlg := FSmimeAlg;
+ FIdAlgEsdh := FSmimeAlg.Branch('5');
+ FIdAlgCms3DesWrap := FSmimeAlg.Branch('6');
+ FIdAlgCmsRC2Wrap := FSmimeAlg.Branch('7');
+ FIdAlgZlibCompress := FSmimeAlg.Branch('8');
+ FIdAlgPwriKek := FSmimeAlg.Branch('9');
+ FIdAlgSsdh := FSmimeAlg.Branch('10');
+ FId_aa_cmsAlgorithmProtect := TDerObjectIdentifier.Create(Pkcs9 + '.52');
+ FIdRsaKem := FSmimeAlg.Branch('14');
+ FIdAlgHssLmsHashsig := FSmimeAlg.Branch('17');
+ FIdAlgAeadChaCha20Poly1305 := FSmimeAlg.Branch('18');
+ FDhSinglePassStdDHHkdfSha256Scheme := FSmimeAlg.Branch('19');
+ FDhSinglePassStdDHHkdfSha384Scheme := FSmimeAlg.Branch('20');
+ FDhSinglePassStdDHHkdfSha512Scheme := FSmimeAlg.Branch('21');
+ FIdAlgHkdfWithSha256 := FSmimeAlg.Branch('28');
+ FIdAlgHkdfWithSha384 := FSmimeAlg.Branch('29');
+ FIdAlgHkdfWithSha512 := FSmimeAlg.Branch('30');
+ FPreferSignedData := FPkcs9AtSmimeCapabilities.Branch('1');
+ FCannotDecryptAny := FPkcs9AtSmimeCapabilities.Branch('2');
+ FSmimeCapabilitiesVersions := FPkcs9AtSmimeCapabilities.Branch('3');
+ FId_ct := FIdSmime.Branch('1');
+ FIdCTAuthData := FId_ct.Branch('2');
+ FIdCTTstInfo := FId_ct.Branch('4');
+ FIdCTCompressedData := FId_ct.Branch('9');
+ FIdCTAuthEnvelopedData := FId_ct.Branch('23');
+ FIdCTTimestampedData := FId_ct.Branch('31');
+ FId_cti := FIdSmime.Branch('6');
+ FIdCtiEtsProofOfOrigin := FId_cti.Branch('1');
+ FIdCtiEtsProofOfReceipt := FId_cti.Branch('2');
+ FIdCtiEtsProofOfDelivery := FId_cti.Branch('3');
+ FIdCtiEtsProofOfSender := FId_cti.Branch('4');
+ FIdCtiEtsProofOfApproval := FId_cti.Branch('5');
+ FIdCtiEtsProofOfCreation := FId_cti.Branch('6');
+ FId_aa := FIdSmime.Branch('2');
+ FIdAAOid := FId_aa;
+ FPkcs9AtBinarySigningTime := FId_aa.Branch('46');
+ FIdAAReceiptRequest := FId_aa.Branch('1');
+ FIdAAContentHint := FId_aa.Branch('4');
+ FIdAAMsgSigDigest := FId_aa.Branch('5');
+ FIdAAContentReference := FId_aa.Branch('10');
+ FIdAAEncrypKeyPref := FId_aa.Branch('11');
+ FIdAASigningCertificate := FId_aa.Branch('12');
+ FIdAAContentIdentifier := FId_aa.Branch('7');
+ FIdAASignatureTimeStampToken := FId_aa.Branch('14');
+ FIdAAEtsSigPolicyID := FId_aa.Branch('15');
+ FIdAAEtsCommitmentType := FId_aa.Branch('16');
+ FIdAAEtsSignerLocation := FId_aa.Branch('17');
+ FIdAAEtsSignerAttr := FId_aa.Branch('18');
+ FIdAAEtsOtherSigCert := FId_aa.Branch('19');
+ FIdAAEtsContentTimestamp := FId_aa.Branch('20');
+ FIdAAEtsCertificateRefs := FId_aa.Branch('21');
+ FIdAAEtsRevocationRefs := FId_aa.Branch('22');
+ FIdAAEtsCertValues := FId_aa.Branch('23');
+ FIdAAEtsRevocationValues := FId_aa.Branch('24');
+ FIdAAEtsEscTimeStamp := FId_aa.Branch('25');
+ FIdAAEtsCertCrlTimestamp := FId_aa.Branch('26');
+ FIdAAEtsArchiveTimestamp := FId_aa.Branch('27');
+ FIdAADecryptKeyID := FId_aa.Branch('37');
+ FIdAAImplCryptoAlgs := FId_aa.Branch('38');
+ FIdAAAsymmDecryptKeyID := FId_aa.Branch('54');
+ FIdAAImplCompressAlgs := FId_aa.Branch('43');
+ FIdAACommunityIdentifiers := FId_aa.Branch('40');
+ FIdAASigningCertificateV2 := FId_aa.Branch('47');
+ FIdAAEtsArchiveTimestampV2 := FId_aa.Branch('48');
+ FId_spq := FIdSmime.Branch('5');
+ FIdSpqEtsUri := FId_spq.Branch('1');
+ FIdSpqEtsUNotice := FId_spq.Branch('2');
+ // PKCS#12
+ FKeyBag := TDerObjectIdentifier.Create(BagTypes + '.1');
+ FPkcs8ShroudedKeyBag := TDerObjectIdentifier.Create(BagTypes + '.2');
+ FCertBag := TDerObjectIdentifier.Create(BagTypes + '.3');
+ FCrlBag := TDerObjectIdentifier.Create(BagTypes + '.4');
+ FSecretBag := TDerObjectIdentifier.Create(BagTypes + '.5');
+ FSafeContentsBag := TDerObjectIdentifier.Create(BagTypes + '.6');
+ FPbeWithShaAnd128BitRC4 := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.1');
+ FPbeWithShaAnd40BitRC4 := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.2');
+ FPbeWithShaAnd3KeyTripleDesCbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.3');
+ FPbeWithShaAnd2KeyTripleDesCbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.4');
+ FPbeWithShaAnd128BitRC2Cbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.5');
+ FPbewithShaAnd40BitRC2Cbc := TDerObjectIdentifier.Create(Pkcs12PbeIds + '.6');
end;
end.
diff --git a/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas b/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas
index 5d1f62b2..21a6ef65 100644
--- a/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/Pkcs/ClpPkcsRsaAsn1Objects.pas
@@ -110,8 +110,6 @@ TRsassaPssParameters = class(TAsn1Encodable, IRsassaPssParameters)
class var
FDefaultHashAlgorithm, FDefaultMaskGenAlgorithm: IAlgorithmIdentifier;
FDefaultSaltLength, FDefaultTrailerField: IDerInteger;
-
- class procedure Boot; static;
class constructor Create;
class function GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier; static;
class function GetTaggedDerInteger(ATagged: IAsn1TaggedObject; AState: Boolean): IDerInteger; static;
@@ -172,8 +170,6 @@ TRsaesOaepParameters = class(TAsn1Encodable, IRsaesOaepParameters)
class var
FDefaultHashAlgorithm, FDefaultMaskGenAlgorithm,
FDefaultPSourceAlgorithm: IAlgorithmIdentifier;
-
- class procedure Boot; static;
class constructor Create;
class function GetTaggedAlgorithmIdentifier(ATagged: IAsn1TaggedObject; AState: Boolean): IAlgorithmIdentifier; static;
@@ -390,11 +386,6 @@ function TRsaPrivateKeyStructure.ToAsn1Object: IAsn1Object;
{ TRsassaPssParameters }
class constructor TRsassaPssParameters.Create;
-begin
- Boot;
-end;
-
-class procedure TRsassaPssParameters.Boot;
begin
FDefaultHashAlgorithm := TAlgorithmIdentifier.Create(TOiwObjectIdentifiers.IdSha1, TDerNull.Instance);
FDefaultMaskGenAlgorithm := TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
@@ -583,11 +574,6 @@ function TRsassaPssParameters.ToAsn1Object: IAsn1Object;
{ TRsaesOaepParameters }
class constructor TRsaesOaepParameters.Create;
-begin
- Boot;
-end;
-
-class procedure TRsaesOaepParameters.Boot;
begin
FDefaultHashAlgorithm := TAlgorithmIdentifier.Create(TOiwObjectIdentifiers.IdSha1, TDerNull.Instance);
FDefaultMaskGenAlgorithm := TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdMgf1, DefaultHashAlgorithm);
diff --git a/CryptoLib/src/Asn1/Rosstandart/ClpRosstandartObjectIdentifiers.pas b/CryptoLib/src/Asn1/Rosstandart/ClpRosstandartObjectIdentifiers.pas
index 900fc865..cd93f70c 100644
--- a/CryptoLib/src/Asn1/Rosstandart/ClpRosstandartObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Rosstandart/ClpRosstandartObjectIdentifiers.pas
@@ -28,7 +28,6 @@ interface
TRosstandartObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FRosstandart, FIdTc26, FIdTc26Gost3411_12_256, FIdTc26Gost3411_12_512,
FIdTc26HmacGost3411_12_256, FIdTc26HmacGost3411_12_512,
FIdTc26Gost3410_12_256, FIdTc26Gost3410_12_512,
@@ -89,8 +88,6 @@ TRosstandartObjectIdentifiers = class abstract(TObject)
class property IdTc26Gost3410_12_512ParamSetB: IDerObjectIdentifier read GetIdTc26Gost3410_12_512ParamSetB;
class property IdTc26Gost3410_12_512ParamSetC: IDerObjectIdentifier read GetIdTc26Gost3410_12_512ParamSetC;
class property IdTc26Gost28147ParamZ: IDerObjectIdentifier read GetIdTc26Gost28147ParamZ;
-
- class procedure Boot; static;
end;
implementation
@@ -99,39 +96,29 @@ implementation
class constructor TRosstandartObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TRosstandartObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FRosstandart := TDerObjectIdentifier.Create('1.2.643.7');
- FIdTc26 := FRosstandart.Branch('1');
- FIdTc26Gost3411_12_256 := FIdTc26.Branch('1.2.2');
- FIdTc26Gost3411_12_512 := FIdTc26.Branch('1.2.3');
- FIdTc26HmacGost3411_12_256 := FIdTc26.Branch('1.4.1');
- FIdTc26HmacGost3411_12_512 := FIdTc26.Branch('1.4.2');
- FIdTc26Gost3410_12_256 := FIdTc26.Branch('1.1.1');
- FIdTc26Gost3410_12_512 := FIdTc26.Branch('1.1.2');
- FIdTc26SignWithDigestGost3410_12_256 := FIdTc26.Branch('1.3.2');
- FIdTc26SignWithDigestGost3410_12_512 := FIdTc26.Branch('1.3.3');
- FIdTc26Agreement := FIdTc26.Branch('1.6');
- FIdTc26AgreementGost3410_12_256 := FIdTc26Agreement.Branch('1');
- FIdTc26AgreementGost3410_12_512 := FIdTc26Agreement.Branch('2');
- FIdTc26Gost3410_12_256ParamSet := FIdTc26.Branch('2.1.1');
- FIdTc26Gost3410_12_256ParamSetA := FIdTc26Gost3410_12_256ParamSet.Branch('1');
- FIdTc26Gost3410_12_256ParamSetB := FIdTc26Gost3410_12_256ParamSet.Branch('2');
- FIdTc26Gost3410_12_256ParamSetC := FIdTc26Gost3410_12_256ParamSet.Branch('3');
- FIdTc26Gost3410_12_256ParamSetD := FIdTc26Gost3410_12_256ParamSet.Branch('4');
- FIdTc26Gost3410_12_512ParamSet := FIdTc26.Branch('2.1.2');
- FIdTc26Gost3410_12_512ParamSetA := FIdTc26Gost3410_12_512ParamSet.Branch('1');
- FIdTc26Gost3410_12_512ParamSetB := FIdTc26Gost3410_12_512ParamSet.Branch('2');
- FIdTc26Gost3410_12_512ParamSetC := FIdTc26Gost3410_12_512ParamSet.Branch('3');
- FIdTc26Gost28147ParamZ := FIdTc26.Branch('2.5.1.1');
-
- FIsBooted := True;
- end;
+ FRosstandart := TDerObjectIdentifier.Create('1.2.643.7');
+ FIdTc26 := FRosstandart.Branch('1');
+ FIdTc26Gost3411_12_256 := FIdTc26.Branch('1.2.2');
+ FIdTc26Gost3411_12_512 := FIdTc26.Branch('1.2.3');
+ FIdTc26HmacGost3411_12_256 := FIdTc26.Branch('1.4.1');
+ FIdTc26HmacGost3411_12_512 := FIdTc26.Branch('1.4.2');
+ FIdTc26Gost3410_12_256 := FIdTc26.Branch('1.1.1');
+ FIdTc26Gost3410_12_512 := FIdTc26.Branch('1.1.2');
+ FIdTc26SignWithDigestGost3410_12_256 := FIdTc26.Branch('1.3.2');
+ FIdTc26SignWithDigestGost3410_12_512 := FIdTc26.Branch('1.3.3');
+ FIdTc26Agreement := FIdTc26.Branch('1.6');
+ FIdTc26AgreementGost3410_12_256 := FIdTc26Agreement.Branch('1');
+ FIdTc26AgreementGost3410_12_512 := FIdTc26Agreement.Branch('2');
+ FIdTc26Gost3410_12_256ParamSet := FIdTc26.Branch('2.1.1');
+ FIdTc26Gost3410_12_256ParamSetA := FIdTc26Gost3410_12_256ParamSet.Branch('1');
+ FIdTc26Gost3410_12_256ParamSetB := FIdTc26Gost3410_12_256ParamSet.Branch('2');
+ FIdTc26Gost3410_12_256ParamSetC := FIdTc26Gost3410_12_256ParamSet.Branch('3');
+ FIdTc26Gost3410_12_256ParamSetD := FIdTc26Gost3410_12_256ParamSet.Branch('4');
+ FIdTc26Gost3410_12_512ParamSet := FIdTc26.Branch('2.1.2');
+ FIdTc26Gost3410_12_512ParamSetA := FIdTc26Gost3410_12_512ParamSet.Branch('1');
+ FIdTc26Gost3410_12_512ParamSetB := FIdTc26Gost3410_12_512ParamSet.Branch('2');
+ FIdTc26Gost3410_12_512ParamSetC := FIdTc26Gost3410_12_512ParamSet.Branch('3');
+ FIdTc26Gost28147ParamZ := FIdTc26.Branch('2.5.1.1');
end;
class function TRosstandartObjectIdentifiers.GetIdTc26: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas b/CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas
index 3d0dc2be..5ce8bb8a 100644
--- a/CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas
+++ b/CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas
@@ -64,10 +64,8 @@ TSecNamedCurves = class sealed(TObject)
class procedure DefineCurve(const AName: String;
const AOid: IDerObjectIdentifier;
const AHolder: IX9ECParametersHolder); static;
-
- class procedure Boot; static;
- class constructor CreateSecNamedCurves;
- class destructor DestroySecNamedCurves;
+ class constructor Create;
+ class destructor Destroy;
public
class function GetByName(const AName: String): IX9ECParameters;
@@ -361,7 +359,7 @@ class procedure TSecNamedCurves.DefineCurve(const AName: String;
FObjIds.Add(LName, AOid);
end;
-class procedure TSecNamedCurves.Boot;
+class constructor TSecNamedCurves.Create;
begin
FObjIds := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FCurves := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
@@ -403,12 +401,7 @@ class procedure TSecNamedCurves.Boot;
DefineCurve('sect571r1', TSecObjectIdentifiers.SecT571r1, TSect571r1Holder.Instance);
end;
-class constructor TSecNamedCurves.CreateSecNamedCurves;
-begin
- Boot;
-end;
-
-class destructor TSecNamedCurves.DestroySecNamedCurves;
+class destructor TSecNamedCurves.Destroy;
begin
FObjIds.Free;
FCurves.Free;
diff --git a/CryptoLib/src/Asn1/Sec/ClpSecObjectIdentifiers.pas b/CryptoLib/src/Asn1/Sec/ClpSecObjectIdentifiers.pas
index 2f041cd9..8b296b04 100644
--- a/CryptoLib/src/Asn1/Sec/ClpSecObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/Sec/ClpSecObjectIdentifiers.pas
@@ -30,7 +30,6 @@ interface
TSecObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FCerticom, FEllipticCurve, FSecT163k1, FSecT163r1, FSecT239k1, FSecT113r1, FSecT113r2,
FSecP112r1, FSecP112r2, FSecP160r1, FSecP160k1, FSecP256k1, FSecT163r2,
FSecT283k1, FSecT283r1, FSecT131r1, FSecT131r2, FSecT193r1, FSecT193r2,
@@ -198,8 +197,6 @@ TSecObjectIdentifiers = class abstract(TObject)
class property MqvFullSha256KdfScheme: IDerObjectIdentifier read GetMqvFullSha256KdfScheme;
class property MqvFullSha384KdfScheme: IDerObjectIdentifier read GetMqvFullSha384KdfScheme;
class property MqvFullSha512KdfScheme: IDerObjectIdentifier read GetMqvFullSha512KdfScheme;
-
- class procedure Boot; static;
end;
implementation
@@ -208,98 +205,86 @@ implementation
class constructor TSecObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TSecObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- TX9ObjectIdentifiers.Boot;
-
- FCerticom := TDerObjectIdentifier.Create('1.3.132');
- FEllipticCurve := FCerticom.Branch('0');
- FSecT163k1 := FEllipticCurve.Branch('1');
- FSecT163r1 := FEllipticCurve.Branch('2');
- FSecT239k1 := FEllipticCurve.Branch('3');
- FSecT113r1 := FEllipticCurve.Branch('4');
- FSecT113r2 := FEllipticCurve.Branch('5');
- FSecP112r1 := FEllipticCurve.Branch('6');
- FSecP112r2 := FEllipticCurve.Branch('7');
- FSecP160r1 := FEllipticCurve.Branch('8');
- FSecP160k1 := FEllipticCurve.Branch('9');
- FSecP256k1 := FEllipticCurve.Branch('10');
- FSecT163r2 := FEllipticCurve.Branch('15');
- FSecT283k1 := FEllipticCurve.Branch('16');
- FSecT283r1 := FEllipticCurve.Branch('17');
- FSecT131r1 := FEllipticCurve.Branch('22');
- FSecT131r2 := FEllipticCurve.Branch('23');
- FSecT193r1 := FEllipticCurve.Branch('24');
- FSecT193r2 := FEllipticCurve.Branch('25');
- FSecT233k1 := FEllipticCurve.Branch('26');
- FSecT233r1 := FEllipticCurve.Branch('27');
- FSecP128r1 := FEllipticCurve.Branch('28');
- FSecP128r2 := FEllipticCurve.Branch('29');
- FSecP160r2 := FEllipticCurve.Branch('30');
- FSecP192k1 := FEllipticCurve.Branch('31');
- FSecP224k1 := FEllipticCurve.Branch('32');
- FSecP224r1 := FEllipticCurve.Branch('33');
- FSecP384r1 := FEllipticCurve.Branch('34');
- FSecP521r1 := FEllipticCurve.Branch('35');
- FSecT409k1 := FEllipticCurve.Branch('36');
- FSecT409r1 := FEllipticCurve.Branch('37');
- FSecT571k1 := FEllipticCurve.Branch('38');
- FSecT571r1 := FEllipticCurve.Branch('39');
-
- FSecP192r1 := TX9ObjectIdentifiers.Prime192v1;
- FSecP256r1 := TX9ObjectIdentifiers.Prime256v1;
-
- FSecgScheme := FCerticom.Branch('1');
-
- FDhSinglePassCofactorDHRecommendedKdf := FSecgScheme.Branch('1');
- FDhSinglePassCofactorDHSpecifiedKdf := FSecgScheme.Branch('2');
- FMqvSinglePassRecommendedKdf := FSecgScheme.Branch('3');
- FMqvSinglePassSpecifiedKdf := FSecgScheme.Branch('4');
- FMqvFullRecommendedKdf := FSecgScheme.Branch('5');
- FMqvFullSpecifiedKdf := FSecgScheme.Branch('6');
- FEciesRecommendedParameters := FSecgScheme.Branch('7');
- FEciesSpecifiedParameters := FSecgScheme.Branch('8');
-
- FDhSinglePassStdDHKdfSchemes := FSecgScheme.Branch('11');
- FDhSinglePassStdDHSha224KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('0');
- FDhSinglePassStdDHSha256KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('1');
- FDhSinglePassStdDHSha384KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('2');
- FDhSinglePassStdDHSha512KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('3');
-
- FEcdh := FSecgScheme.Branch('12');
- FEcmqv := FSecgScheme.Branch('13');
-
- FDhSinglePassCofactorDHKdfSchemes := FSecgScheme.Branch('14');
- FDhSinglePassCofactorDHSha224KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('0');
- FDhSinglePassCofactorDHSha256KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('1');
- FDhSinglePassCofactorDHSha384KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('2');
- FDhSinglePassCofactorDHSha512KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('3');
-
- FMqvSinglePassKdfSchemes := FSecgScheme.Branch('15');
- FMqvSinglePassSha224KdfScheme := FMqvSinglePassKdfSchemes.Branch('0');
- FMqvSinglePassSha256KdfScheme := FMqvSinglePassKdfSchemes.Branch('1');
- FMqvSinglePassSha384KdfScheme := FMqvSinglePassKdfSchemes.Branch('2');
- FMqvSinglePassSha512KdfScheme := FMqvSinglePassKdfSchemes.Branch('3');
-
- FMqvFullKdfSchemes := FSecgScheme.Branch('16');
- FMqvFullSha224KdfScheme := FMqvFullKdfSchemes.Branch('0');
- FMqvFullSha256KdfScheme := FMqvFullKdfSchemes.Branch('1');
- FMqvFullSha384KdfScheme := FMqvFullKdfSchemes.Branch('2');
- FMqvFullSha512KdfScheme := FMqvFullKdfSchemes.Branch('3');
-
- FKdfAlgorithms := FSecgScheme.Branch('17');
- FX963Kdf := FKdfAlgorithms.Branch('0');
- FNistConcatenationKdf := FKdfAlgorithms.Branch('1');
- FTlsKdf := FKdfAlgorithms.Branch('2');
- FIkev2Kdf := FKdfAlgorithms.Branch('3');
-
- FIsBooted := True;
- end;
+ FCerticom := TDerObjectIdentifier.Create('1.3.132');
+ FEllipticCurve := FCerticom.Branch('0');
+ FSecT163k1 := FEllipticCurve.Branch('1');
+ FSecT163r1 := FEllipticCurve.Branch('2');
+ FSecT239k1 := FEllipticCurve.Branch('3');
+ FSecT113r1 := FEllipticCurve.Branch('4');
+ FSecT113r2 := FEllipticCurve.Branch('5');
+ FSecP112r1 := FEllipticCurve.Branch('6');
+ FSecP112r2 := FEllipticCurve.Branch('7');
+ FSecP160r1 := FEllipticCurve.Branch('8');
+ FSecP160k1 := FEllipticCurve.Branch('9');
+ FSecP256k1 := FEllipticCurve.Branch('10');
+ FSecT163r2 := FEllipticCurve.Branch('15');
+ FSecT283k1 := FEllipticCurve.Branch('16');
+ FSecT283r1 := FEllipticCurve.Branch('17');
+ FSecT131r1 := FEllipticCurve.Branch('22');
+ FSecT131r2 := FEllipticCurve.Branch('23');
+ FSecT193r1 := FEllipticCurve.Branch('24');
+ FSecT193r2 := FEllipticCurve.Branch('25');
+ FSecT233k1 := FEllipticCurve.Branch('26');
+ FSecT233r1 := FEllipticCurve.Branch('27');
+ FSecP128r1 := FEllipticCurve.Branch('28');
+ FSecP128r2 := FEllipticCurve.Branch('29');
+ FSecP160r2 := FEllipticCurve.Branch('30');
+ FSecP192k1 := FEllipticCurve.Branch('31');
+ FSecP224k1 := FEllipticCurve.Branch('32');
+ FSecP224r1 := FEllipticCurve.Branch('33');
+ FSecP384r1 := FEllipticCurve.Branch('34');
+ FSecP521r1 := FEllipticCurve.Branch('35');
+ FSecT409k1 := FEllipticCurve.Branch('36');
+ FSecT409r1 := FEllipticCurve.Branch('37');
+ FSecT571k1 := FEllipticCurve.Branch('38');
+ FSecT571r1 := FEllipticCurve.Branch('39');
+
+ FSecP192r1 := TX9ObjectIdentifiers.Prime192v1;
+ FSecP256r1 := TX9ObjectIdentifiers.Prime256v1;
+
+ FSecgScheme := FCerticom.Branch('1');
+
+ FDhSinglePassCofactorDHRecommendedKdf := FSecgScheme.Branch('1');
+ FDhSinglePassCofactorDHSpecifiedKdf := FSecgScheme.Branch('2');
+ FMqvSinglePassRecommendedKdf := FSecgScheme.Branch('3');
+ FMqvSinglePassSpecifiedKdf := FSecgScheme.Branch('4');
+ FMqvFullRecommendedKdf := FSecgScheme.Branch('5');
+ FMqvFullSpecifiedKdf := FSecgScheme.Branch('6');
+ FEciesRecommendedParameters := FSecgScheme.Branch('7');
+ FEciesSpecifiedParameters := FSecgScheme.Branch('8');
+
+ FDhSinglePassStdDHKdfSchemes := FSecgScheme.Branch('11');
+ FDhSinglePassStdDHSha224KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('0');
+ FDhSinglePassStdDHSha256KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('1');
+ FDhSinglePassStdDHSha384KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('2');
+ FDhSinglePassStdDHSha512KdfScheme := FDhSinglePassStdDHKdfSchemes.Branch('3');
+
+ FEcdh := FSecgScheme.Branch('12');
+ FEcmqv := FSecgScheme.Branch('13');
+
+ FDhSinglePassCofactorDHKdfSchemes := FSecgScheme.Branch('14');
+ FDhSinglePassCofactorDHSha224KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('0');
+ FDhSinglePassCofactorDHSha256KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('1');
+ FDhSinglePassCofactorDHSha384KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('2');
+ FDhSinglePassCofactorDHSha512KdfScheme := FDhSinglePassCofactorDHKdfSchemes.Branch('3');
+
+ FMqvSinglePassKdfSchemes := FSecgScheme.Branch('15');
+ FMqvSinglePassSha224KdfScheme := FMqvSinglePassKdfSchemes.Branch('0');
+ FMqvSinglePassSha256KdfScheme := FMqvSinglePassKdfSchemes.Branch('1');
+ FMqvSinglePassSha384KdfScheme := FMqvSinglePassKdfSchemes.Branch('2');
+ FMqvSinglePassSha512KdfScheme := FMqvSinglePassKdfSchemes.Branch('3');
+
+ FMqvFullKdfSchemes := FSecgScheme.Branch('16');
+ FMqvFullSha224KdfScheme := FMqvFullKdfSchemes.Branch('0');
+ FMqvFullSha256KdfScheme := FMqvFullKdfSchemes.Branch('1');
+ FMqvFullSha384KdfScheme := FMqvFullKdfSchemes.Branch('2');
+ FMqvFullSha512KdfScheme := FMqvFullKdfSchemes.Branch('3');
+
+ FKdfAlgorithms := FSecgScheme.Branch('17');
+ FX963Kdf := FKdfAlgorithms.Branch('0');
+ FNistConcatenationKdf := FKdfAlgorithms.Branch('1');
+ FTlsKdf := FKdfAlgorithms.Branch('2');
+ FIkev2Kdf := FKdfAlgorithms.Branch('3');
end;
class function TSecObjectIdentifiers.GetCerticom: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTNamedCurves.pas b/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTNamedCurves.pas
index 8a1d28cf..b9409eaf 100644
--- a/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTNamedCurves.pas
+++ b/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTNamedCurves.pas
@@ -56,10 +56,8 @@ TTeleTrusTNamedCurves = class sealed(TObject)
class procedure DefineCurve(const AName: String;
const AOid: IDerObjectIdentifier;
const AHolder: IX9ECParametersHolder); static;
-
- class procedure Boot; static;
- class constructor CreateTeleTrusTNamedCurves;
- class destructor DestroyTeleTrusTNamedCurves;
+ class constructor Create;
+ class destructor Destroy;
public
class function GetByName(const AName: String): IX9ECParameters;
@@ -211,7 +209,7 @@ class procedure TTeleTrusTNamedCurves.DefineCurve(const AName: String;
FObjIds.Add(LName, AOid);
end;
-class procedure TTeleTrusTNamedCurves.Boot;
+class constructor TTeleTrusTNamedCurves.Create;
begin
FObjIds := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FCurves := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
@@ -233,12 +231,7 @@ class procedure TTeleTrusTNamedCurves.Boot;
DefineCurve('brainpoolP512t1', TTeleTrusTObjectIdentifiers.BrainpoolP512T1, TBrainpoolP512t1Holder.Instance);
end;
-class constructor TTeleTrusTNamedCurves.CreateTeleTrusTNamedCurves;
-begin
- Boot;
-end;
-
-class destructor TTeleTrusTNamedCurves.DestroyTeleTrusTNamedCurves;
+class destructor TTeleTrusTNamedCurves.Destroy;
begin
FObjIds.Free;
FCurves.Free;
diff --git a/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTObjectIdentifiers.pas b/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTObjectIdentifiers.pas
index dc59e32c..a1b31780 100644
--- a/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/TeleTrust/ClpTeleTrusTObjectIdentifiers.pas
@@ -30,8 +30,6 @@ TTeleTrusTObjectIdentifiers = class sealed(TObject)
strict private
class var
-
- FIsBooted: Boolean;
FTeleTrusT, FAlgorithm, FEncryptionAlgorithm, FHashAlgorithm,
FSignatureAlgorithm, FSignatureScheme,
FRipeMD160, FRipeMD128, FRipeMD256,
@@ -136,9 +134,6 @@ TTeleTrusTObjectIdentifiers = class sealed(TObject)
read GetBrainpoolP512R1;
class property BrainpoolP512T1: IDerObjectIdentifier
read GetBrainpoolP512T1;
-
- class procedure Boot(); static;
-
end;
implementation
@@ -325,65 +320,55 @@ class function TTeleTrusTObjectIdentifiers.GetBrainpoolP512T1: IDerObjectIdentif
Result := FBrainpoolP512T1;
end;
-class procedure TTeleTrusTObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- // Base OID: 1.3.36
- FTeleTrusT := TDerObjectIdentifier.Create('1.3.36');
- FAlgorithm := FTeleTrusT.Branch('3');
-
- // Algorithm sub-branches
- FEncryptionAlgorithm := FAlgorithm.Branch('1');
- FHashAlgorithm := FAlgorithm.Branch('2');
- FSignatureAlgorithm := FAlgorithm.Branch('3');
- FSignatureScheme := FAlgorithm.Branch('4');
-
- // Hash algorithms
- FRipeMD160 := FHashAlgorithm.Branch('1');
- FRipeMD128 := FHashAlgorithm.Branch('2');
- FRipeMD256 := FHashAlgorithm.Branch('3');
-
- // RSA Signatures
- FRsaSignature := FSignatureAlgorithm.Branch('1');
- FRsaSignatureWithRipeMD160 := FRsaSignature.Branch('2');
- FRsaSignatureWithRipeMD128 := FRsaSignature.Branch('3');
- FRsaSignatureWithRipeMD256 := FRsaSignature.Branch('4');
-
- // EC Signatures
- FECSign := FSignatureAlgorithm.Branch('2');
- FECSignWithSha1 := FECSign.Branch('1');
- FECSignWithRipeMD160 := FECSign.Branch('2');
- FECSignWithMD2 := FECSign.Branch('3');
- FECSignWithMD5 := FECSign.Branch('4');
- FTttEcg := FECSign.Branch('5');
- FEcStdCurvesAndGeneration := FECSign.Branch('8');
-
- FEllipticCurve := FEcStdCurvesAndGeneration.Branch('1');
- FVersionOne := FEllipticCurve.Branch('1');
-
- FBrainpoolP160R1 := FVersionOne.Branch('1');
- FBrainpoolP160T1 := FVersionOne.Branch('2');
- FBrainpoolP192R1 := FVersionOne.Branch('3');
- FBrainpoolP192T1 := FVersionOne.Branch('4');
- FBrainpoolP224R1 := FVersionOne.Branch('5');
- FBrainpoolP224T1 := FVersionOne.Branch('6');
- FBrainpoolP256R1 := FVersionOne.Branch('7');
- FBrainpoolP256T1 := FVersionOne.Branch('8');
- FBrainpoolP320R1 := FVersionOne.Branch('9');
- FBrainpoolP320T1 := FVersionOne.Branch('10');
- FBrainpoolP384R1 := FVersionOne.Branch('11');
- FBrainpoolP384T1 := FVersionOne.Branch('12');
- FBrainpoolP512R1 := FVersionOne.Branch('13');
- FBrainpoolP512T1 := FVersionOne.Branch('14');
-
- FIsBooted := True;
- end;
-end;
-
class constructor TTeleTrusTObjectIdentifiers.Create;
begin
- Boot;
+ // Base OID: 1.3.36
+ FTeleTrusT := TDerObjectIdentifier.Create('1.3.36');
+ FAlgorithm := FTeleTrusT.Branch('3');
+
+ // Algorithm sub-branches
+ FEncryptionAlgorithm := FAlgorithm.Branch('1');
+ FHashAlgorithm := FAlgorithm.Branch('2');
+ FSignatureAlgorithm := FAlgorithm.Branch('3');
+ FSignatureScheme := FAlgorithm.Branch('4');
+
+ // Hash algorithms
+ FRipeMD160 := FHashAlgorithm.Branch('1');
+ FRipeMD128 := FHashAlgorithm.Branch('2');
+ FRipeMD256 := FHashAlgorithm.Branch('3');
+
+ // RSA Signatures
+ FRsaSignature := FSignatureAlgorithm.Branch('1');
+ FRsaSignatureWithRipeMD160 := FRsaSignature.Branch('2');
+ FRsaSignatureWithRipeMD128 := FRsaSignature.Branch('3');
+ FRsaSignatureWithRipeMD256 := FRsaSignature.Branch('4');
+
+ // EC Signatures
+ FECSign := FSignatureAlgorithm.Branch('2');
+ FECSignWithSha1 := FECSign.Branch('1');
+ FECSignWithRipeMD160 := FECSign.Branch('2');
+ FECSignWithMD2 := FECSign.Branch('3');
+ FECSignWithMD5 := FECSign.Branch('4');
+ FTttEcg := FECSign.Branch('5');
+ FEcStdCurvesAndGeneration := FECSign.Branch('8');
+
+ FEllipticCurve := FEcStdCurvesAndGeneration.Branch('1');
+ FVersionOne := FEllipticCurve.Branch('1');
+
+ FBrainpoolP160R1 := FVersionOne.Branch('1');
+ FBrainpoolP160T1 := FVersionOne.Branch('2');
+ FBrainpoolP192R1 := FVersionOne.Branch('3');
+ FBrainpoolP192T1 := FVersionOne.Branch('4');
+ FBrainpoolP224R1 := FVersionOne.Branch('5');
+ FBrainpoolP224T1 := FVersionOne.Branch('6');
+ FBrainpoolP256R1 := FVersionOne.Branch('7');
+ FBrainpoolP256T1 := FVersionOne.Branch('8');
+ FBrainpoolP320R1 := FVersionOne.Branch('9');
+ FBrainpoolP320T1 := FVersionOne.Branch('10');
+ FBrainpoolP384R1 := FVersionOne.Branch('11');
+ FBrainpoolP384T1 := FVersionOne.Branch('12');
+ FBrainpoolP512R1 := FVersionOne.Branch('13');
+ FBrainpoolP512T1 := FVersionOne.Branch('14');
end;
end.
diff --git a/CryptoLib/src/Asn1/X500/Style/ClpIetfUtilities.pas b/CryptoLib/src/Asn1/X500/Style/ClpIetfUtilities.pas
index 304024bf..b0813761 100644
--- a/CryptoLib/src/Asn1/X500/Style/ClpIetfUtilities.pas
+++ b/CryptoLib/src/Asn1/X500/Style/ClpIetfUtilities.pas
@@ -21,11 +21,14 @@
interface
uses
+ Classes,
SysUtils,
ClpAsn1Core,
ClpIAsn1Core,
ClpIAsn1Objects,
ClpCryptoLibTypes,
+ ClpConverters,
+ ClpStreamUtilities,
ClpStringUtilities,
ClpEncoders;
@@ -42,6 +45,9 @@ TIetfUtilities = class sealed(TObject)
///
class function ConvertHex(AC: Char): Int32; static;
class function DecodeObject(const AOValue: String): IAsn1Object; static;
+ class procedure FlushHexBytes(ABuf: TStringBuilder; AHexBytes: TMemoryStream;
+ var ALastEscaped: Int32); static;
+ class procedure CheckCompleteHexPair(AHex1: Int32); static;
public
///
@@ -70,6 +76,30 @@ implementation
{ TIetfUtilities }
+class procedure TIetfUtilities.FlushHexBytes(ABuf: TStringBuilder;
+ AHexBytes: TMemoryStream; var ALastEscaped: Int32);
+var
+ LHexSlice: TCryptoLibByteArray;
+ LLength: Int32;
+begin
+ LLength := AHexBytes.Position;
+ if LLength > 0 then
+ begin
+ SetLength(LHexSlice, LLength);
+ AHexBytes.Position := 0;
+ AHexBytes.Read(LHexSlice[0], LLength);
+ AHexBytes.Position := 0;
+ ABuf.Append(TConverters.ConvertBytesToString(LHexSlice, TEncoding.UTF8));
+ ALastEscaped := ABuf.Length - 1;
+ end;
+end;
+
+class procedure TIetfUtilities.CheckCompleteHexPair(AHex1: Int32);
+begin
+ if AHex1 >= 0 then
+ raise EArgumentCryptoLibException.Create('invalid hex escape in directory string');
+end;
+
class function TIetfUtilities.IsHexDigit(AC: Char): Boolean;
begin
Result := (('0' <= AC) and (AC <= '9')) or (('a' <= AC) and (AC <= 'f')) or (('A' <= AC) and (AC <= 'F'));
@@ -104,10 +134,10 @@ class function TIetfUtilities.DecodeObject(const AOValue: String): IAsn1Object;
class function TIetfUtilities.Unescape(const AElt: String): String;
var
LSb: TStringBuilder;
- LStart, LI, LLastEscaped: Int32;
+ LHexBytes: TMemoryStream;
+ LStart, LI, LLastEscaped, LHex1, LHexDigit: Int32;
LEscaped, LQuoted, LNonWhiteSpaceEncountered: Boolean;
LC: Char;
- LHex1: Int32;
begin
if System.Length(AElt) < 1 then
begin
@@ -124,38 +154,37 @@ class function TIetfUtilities.Unescape(const AElt: String): String;
LEscaped := False;
LQuoted := False;
LSb := TStringBuilder.Create(System.Length(AElt));
+ LHexBytes := TMemoryStream.Create;
try
-
LStart := 1;
if (System.Length(AElt) > 0) and (AElt[1] = '\') then
begin
if (System.Length(AElt) > 1) and (AElt[2] = '#') then
begin
- LStart := 3; // Skip '\#' (positions 1 and 2)
+ LStart := 3;
LSb.Append('\#');
end;
end;
LNonWhiteSpaceEncountered := False;
- LLastEscaped := 0;
- LHex1 := 0; // Store as Int32 (0 = no hex digit waiting)
+ LLastEscaped := -1;
+ LHex1 := -1;
for LI := LStart to System.Length(AElt) do
begin
LC := AElt[LI];
- // nonWhiteSpaceEncountered = true;
if LC <> ' ' then
LNonWhiteSpaceEncountered := True;
if LC = '"' then
begin
if not LEscaped then
- begin
- LQuoted := not LQuoted;
- end
+ LQuoted := not LQuoted
else
begin
+ CheckCompleteHexPair(LHex1);
+ FlushHexBytes(LSb, LHexBytes, LLastEscaped);
LSb.Append(LC);
LEscaped := False;
end;
@@ -165,34 +194,41 @@ class function TIetfUtilities.Unescape(const AElt: String): String;
LEscaped := True;
LLastEscaped := LSb.Length;
end
- else
+ else if (LC = ' ') and (not LEscaped) and (not LNonWhiteSpaceEncountered) then
begin
- if (LC = ' ') and (not LEscaped) and (not LNonWhiteSpaceEncountered) then
- begin
- Continue;
- end;
- if LEscaped and IsHexDigit(LC) then
+ Continue;
+ end
+ else if LEscaped and IsHexDigit(LC) then
+ begin
+ LHexDigit := ConvertHex(LC);
+ if LHex1 < 0 then
+ LHex1 := LHexDigit
+ else
begin
- if LHex1 <> 0 then
- begin
- LSb.Append(Chr(ConvertHex(Chr(LHex1)) * 16 + ConvertHex(LC)));
- LEscaped := False;
- LHex1 := 0;
- Continue;
- end;
- LHex1 := Ord(LC);
- Continue;
+ LHexBytes.WriteByte(Byte(LHex1 * 16 + LHexDigit));
+ LEscaped := False;
+ LHex1 := -1;
end;
+ end
+ else
+ begin
+ // A '\' followed by a single hex digit and then a non-hex char is an
+ // incomplete hexpair (RFC 4514 sec. 2.4 requires two), not a literal.
+ CheckCompleteHexPair(LHex1);
+ FlushHexBytes(LSb, LHexBytes, LLastEscaped);
LSb.Append(LC);
LEscaped := False;
end;
end;
+ // A '\' followed by a single hex digit at end of input is likewise incomplete.
+ CheckCompleteHexPair(LHex1);
+ FlushHexBytes(LSb, LHexBytes, LLastEscaped);
+
if LSb.Length > 0 then
begin
- while (LSb.Length > 0) and
- (LSb.Chars[LSb.Length - 1] = ' ') and
- (LLastEscaped <> LSb.Length - 1) do
+ while (LSb.Length > 0) and (LSb.Chars[LSb.Length - 1] = ' ') and
+ (LLastEscaped < LSb.Length - 1) do
begin
LSb.Length := LSb.Length - 1;
end;
@@ -201,6 +237,7 @@ class function TIetfUtilities.Unescape(const AElt: String): String;
else
Result := '';
finally
+ LHexBytes.Free;
LSb.Free;
end;
end;
diff --git a/CryptoLib/src/Asn1/X509/ClpX509Asn1Generators.pas b/CryptoLib/src/Asn1/X509/ClpX509Asn1Generators.pas
index e26f0bc0..9ad1e368 100644
--- a/CryptoLib/src/Asn1/X509/ClpX509Asn1Generators.pas
+++ b/CryptoLib/src/Asn1/X509/ClpX509Asn1Generators.pas
@@ -175,8 +175,6 @@ TX509ExtensionsGenerator = class(TInterfacedObject, IX509ExtensionsGenerator)
strict private
class var
FDupsAllowed: TDictionary;
-
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -677,16 +675,6 @@ function TV2AttributeCertificateInfoGenerator.GenerateAttributeCertificateInfo:
{ TX509ExtensionsGenerator }
class constructor TX509ExtensionsGenerator.Create;
-begin
- Boot;
-end;
-
-class destructor TX509ExtensionsGenerator.Destroy;
-begin
- FDupsAllowed.Free;
-end;
-
-class procedure TX509ExtensionsGenerator.Boot;
begin
FDupsAllowed := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
// OIDs that allow duplicate extensions
@@ -696,6 +684,11 @@ class procedure TX509ExtensionsGenerator.Boot;
FDupsAllowed.Add(TX509Extensions.CertificateIssuer, True);
end;
+class destructor TX509ExtensionsGenerator.Destroy;
+begin
+ FDupsAllowed.Free;
+end;
+
constructor TX509ExtensionsGenerator.Create;
begin
inherited Create();
diff --git a/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas b/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas
index c46330eb..988c1804 100644
--- a/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas
+++ b/CryptoLib/src/Asn1/X509/ClpX509Asn1Objects.pas
@@ -1,4 +1,4 @@
-{ *********************************************************************************** }
+{ *********************************************************************************** }
{ * CryptoLib Library * }
{ * Author - Ugochukwu Mmaduekwe * }
{ * Github Repository * }
@@ -555,10 +555,7 @@ TX509Extensions = class(TAsn1Encodable, IX509Extensions)
FAltSignatureAlgorithm: IDerObjectIdentifier;
FAltSignatureValue: IDerObjectIdentifier;
FDraftDeltaCertificateDescriptor: IDerObjectIdentifier;
-
- class procedure Boot; static;
class constructor Create;
- class destructor Destroy;
strict protected
function GetCount: Int32;
@@ -671,6 +668,7 @@ TKeyPurposeId = class abstract(TObject)
FIdKpCmcCa: IDerObjectIdentifier;
FIdKpCmcRa: IDerObjectIdentifier;
FIdKpCmKga: IDerObjectIdentifier;
+ FIdKpDocumentSigning: IDerObjectIdentifier;
FIdKpConfigSigning: IDerObjectIdentifier;
FIdKpTrustAnchorConfigSigning: IDerObjectIdentifier;
FIdKpUpdatePackageSigning: IDerObjectIdentifier;
@@ -709,6 +707,7 @@ TKeyPurposeId = class abstract(TObject)
class function GetIdKpCmcCa: IDerObjectIdentifier; static; inline;
class function GetIdKpCmcRa: IDerObjectIdentifier; static; inline;
class function GetIdKpCmKga: IDerObjectIdentifier; static; inline;
+ class function GetIdKpDocumentSigning: IDerObjectIdentifier; static; inline;
class function GetIdKpConfigSigning: IDerObjectIdentifier; static; inline;
class function GetIdKpTrustAnchorConfigSigning: IDerObjectIdentifier; static; inline;
class function GetIdKpUpdatePackageSigning: IDerObjectIdentifier; static; inline;
@@ -723,8 +722,6 @@ TKeyPurposeId = class abstract(TObject)
class function GetKeyPurposeClientAuth: IDerObjectIdentifier; static; inline;
class function GetKeyPurposeKdc: IDerObjectIdentifier; static; inline;
class function GetIdKpNsSgc: IDerObjectIdentifier; static; inline;
-
- class procedure Boot; static;
class constructor Create;
public
@@ -751,6 +748,8 @@ TKeyPurposeId = class abstract(TObject)
class property IdKpCmcCa: IDerObjectIdentifier read GetIdKpCmcCa;
class property IdKpCmcRa: IDerObjectIdentifier read GetIdKpCmcRa;
class property IdKpCmKga: IDerObjectIdentifier read GetIdKpCmKga;
+ /// RFC 9336 sec. 3.1 — signing documents (e.g. PDF, XML, JSON) for human consumption (id-kp-documentSigning, { id-kp 36 }).
+ class property IdKpDocumentSigning: IDerObjectIdentifier read GetIdKpDocumentSigning;
/// RFC 9809 sec. 3 — signing general-purpose configuration files (id-kp-configSigning, { id-kp 41 }).
class property IdKpConfigSigning: IDerObjectIdentifier read GetIdKpConfigSigning;
/// RFC 9809 sec. 3 — signing trust anchor configuration files (id-kp-trustAnchorConfigSigning, { id-kp 42 }).
@@ -834,8 +833,6 @@ TX509Name = class(TAsn1Encodable, IX509Name, IAsn1Choice)
FJurisdictionC: IDerObjectIdentifier;
FJurisdictionST: IDerObjectIdentifier;
FJurisdictionL: IDerObjectIdentifier;
-
- class procedure Boot; static;
class function GetDefaultReverse: Boolean; static;
class procedure SetDefaultReverse(const AValue: Boolean); static;
class constructor Create;
@@ -1350,7 +1347,7 @@ TTbsCertificateStructure = class(TAsn1Encodable, ITbsCertificateStructure)
public
class constructor Create;
-
+
class function GetInstance(AObj: TObject): ITbsCertificateStructure; overload; static;
///
/// Get instance from ASN.1 convertible.
@@ -1361,10 +1358,10 @@ TTbsCertificateStructure = class(TAsn1Encodable, ITbsCertificateStructure)
AExplicitly: Boolean): ITbsCertificateStructure; overload; static;
class function GetTagged(const ATaggedObject: IAsn1TaggedObject;
ADeclaredExplicit: Boolean): ITbsCertificateStructure; static;
-
+
class function GetAllowNonDERTbsCertificate: Boolean; static;
class procedure SetAllowNonDERTbsCertificate(AValue: Boolean); static;
-
+
class property AllowNonDERTbsCertificate: Boolean read GetAllowNonDERTbsCertificate write SetAllowNonDERTbsCertificate;
constructor Create(const ASeq: IAsn1Sequence); overload;
@@ -1751,9 +1748,23 @@ TObjectDigestInfo = class(TAsn1Encodable, IObjectDigestInfo)
end;
- ///
- /// The DistributionPointName object.
- ///
+ /// The DistributionPointName ASN.1 type.
+ ///
+ ///
+ /// DistributionPointName ::= CHOICE {
+ /// fullName[0] GeneralNames,
+ /// nameRelativeToCRLIssuer[1] RelativeDistinguishedName
+ /// }
+ /// RelativeDistinguishedName ::= SET SIZE(1..MAX) OF AttributeTypeAndValue
+ ///
+ /// Per RFC 5280 sec. 4.2.1.13, nameRelativeToCRLIssuer is a single RelativeDistinguishedName
+ /// (a SET of one or more attribute-type-and-value pairs) - never a sequence of RDNs.
+ /// When two attributes need to be carried here they share one multi-valued RDN
+ /// (e.g. O=ExampleOrg + OU=Test), not two adjacent RDNs (e.g. O=ExampleOrg, OU=Test);
+ /// the CHOICE branch is decoded as a TAsn1Set and a sequence-shaped input is rejected.
+ /// The full DN of the distribution point is formed by appending this single RDN to the CRL
+ /// issuer's RDNSequence (RFC 5280 sec. 5.2.5).
+ ///
TDistributionPointName = class(TAsn1Encodable, IDistributionPointName, IAsn1Choice)
strict private
@@ -1964,15 +1975,16 @@ TDistributionPoint = class(TAsn1Encodable, IDistributionPoint)
end;
+ /// The IssuingDistributionPoint ASN.1 type.
///
///
/// IssuingDistributionPoint ::= SEQUENCE {
- /// distributionPoint [0] DistributionPointName OPTIONAL,
- /// onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
- /// onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
- /// onlySomeReasons [3] ReasonFlags OPTIONAL,
- /// indirectCRL [4] BOOLEAN DEFAULT FALSE,
- /// onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE
+ /// distributionPoint[0] DistributionPointName OPTIONAL,
+ /// onlyContainsUserCerts[1] BOOLEAN DEFAULT FALSE,
+ /// onlyContainsCACerts[2] BOOLEAN DEFAULT FALSE,
+ /// onlySomeReasons[3] ReasonFlags OPTIONAL,
+ /// indirectCRL[4] BOOLEAN DEFAULT FALSE,
+ /// onlyContainsAttributeCerts[5] BOOLEAN DEFAULT FALSE
/// }
///
///
@@ -2009,9 +2021,25 @@ TIssuingDistributionPoint = class(TAsn1Encodable, IIssuingDistributionPoint)
class function GetTagged(const ATaggedObject: IAsn1TaggedObject;
ADeclaredExplicit: Boolean): IIssuingDistributionPoint; static;
+ /// Constructor from given details.
+ /// May contain a URI as pointer to most current CRL.
+ /// Covers revocation information for end certificates.
+ /// Covers revocation information for CA certificates.
+ /// Which revocation reasons this point covers.
+ /// If True then the CRL contains revocation information about certificates issued by other CAs.
+ /// Covers revocation information for attribute certificates.
+ /// Raised when more than one of the onlyContains* flags is True.
constructor Create(const ADistributionPoint: IDistributionPointName;
AOnlyContainsUserCerts, AOnlyContainsCACerts: Boolean;
const AOnlySomeReasons: IReasonFlags; AIndirectCRL, AOnlyContainsAttributeCerts: Boolean); overload;
+ /// Shorthand constructor from given details.
+ /// May contain a URI as pointer to most current CRL.
+ /// If True then the CRL contains revocation information about certificates issued by other CAs.
+ /// Covers revocation information for attribute certificates.
+ /// Raised when more than one of the onlyContains* flags is True.
+ constructor Create(const ADistributionPoint: IDistributionPointName;
+ AIndirectCRL, AOnlyContainsAttributeCerts: Boolean); overload;
+ /// Constructor from Asn1Sequence.
constructor Create(const ASeq: IAsn1Sequence); overload;
function ToAsn1Object: IAsn1Object; override;
@@ -2991,7 +3019,6 @@ class function TValidity.GetInstance(const AEncoded: TCryptoLibByteArray): IVali
Result := TValidity.Create(TAsn1Sequence.GetInstance(AEncoded));
end;
-
class function TValidity.GetInstance(const AObj: IAsn1TaggedObject;
AExplicitly: Boolean): IValidity;
begin
@@ -4894,7 +4921,6 @@ class function TGeneralNames.GetInstance(const AEncoded: TCryptoLibByteArray): I
Result := TGeneralNames.Create(TAsn1Sequence.GetInstance(AEncoded));
end;
-
class function TGeneralNames.GetInstance(const AObj: IAsn1TaggedObject;
AExplicitly: Boolean): IGeneralNames;
begin
@@ -5410,16 +5436,6 @@ function TExtendedKeyUsage.ToAsn1Object: IAsn1Object;
{ TX509Extensions }
class constructor TX509Extensions.Create;
-begin
- Boot;
-end;
-
-class destructor TX509Extensions.Destroy;
-begin
- // Class vars are interface references, no cleanup needed
-end;
-
-class procedure TX509Extensions.Boot;
begin
FSubjectDirectoryAttributes := TDerObjectIdentifier.Create('2.5.29.9');
FSubjectKeyIdentifier := TDerObjectIdentifier.Create('2.5.29.14');
@@ -5462,11 +5478,6 @@ class procedure TX509Extensions.Boot;
{ TKeyPurposeId }
class constructor TKeyPurposeId.Create;
-begin
- Boot;
-end;
-
-class procedure TKeyPurposeId.Boot;
var
LIdKp: IDerObjectIdentifier;
LIdPkinit: String;
@@ -5495,6 +5506,7 @@ class procedure TKeyPurposeId.Boot;
FIdKpCmcCa := TDerObjectIdentifier.Create(LIdKp.ID + '.27');
FIdKpCmcRa := TDerObjectIdentifier.Create(LIdKp.ID + '.28');
FIdKpCmKga := TDerObjectIdentifier.Create(LIdKp.ID + '.32');
+ FIdKpDocumentSigning := TDerObjectIdentifier.Create(LIdKp.ID + '.36');
FIdKpConfigSigning := TDerObjectIdentifier.Create(LIdKp.ID + '.41');
FIdKpTrustAnchorConfigSigning := TDerObjectIdentifier.Create(LIdKp.ID + '.42');
FIdKpUpdatePackageSigning := TDerObjectIdentifier.Create(LIdKp.ID + '.43');
@@ -5627,6 +5639,11 @@ class function TKeyPurposeId.GetIdKpCmKga: IDerObjectIdentifier;
Result := FIdKpCmKga;
end;
+class function TKeyPurposeId.GetIdKpDocumentSigning: IDerObjectIdentifier;
+begin
+ Result := FIdKpDocumentSigning;
+end;
+
class function TKeyPurposeId.GetIdKpConfigSigning: IDerObjectIdentifier;
begin
Result := FIdKpConfigSigning;
@@ -6611,40 +6628,6 @@ function TX509Name.ToAsn1Object: IAsn1Object;
class constructor TX509Name.Create;
begin
FDefaultReverseLock := TCriticalSection.Create();
- Boot;
-end;
-
-class destructor TX509Name.Destroy;
-begin
- FDefaultSymbols.Free;
- FRFC2253Symbols.Free;
- FRFC1779Symbols.Free;
- FDefaultLookup.Free;
- FDefaultReverseLock.Free;
-end;
-
-class function TX509Name.GetDefaultReverse: Boolean;
-begin
- FDefaultReverseLock.Acquire;
- try
- Result := FDefaultReverse;
- finally
- FDefaultReverseLock.Release;
- end;
-end;
-
-class procedure TX509Name.SetDefaultReverse(const AValue: Boolean);
-begin
- FDefaultReverseLock.Acquire;
- try
- FDefaultReverse := AValue;
- finally
- FDefaultReverseLock.Release;
- end;
-end;
-
-class procedure TX509Name.Boot;
-begin
FDefaultReverse := False;
FDefaultSymbols := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
FRFC2253Symbols := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
@@ -6761,6 +6744,8 @@ class procedure TX509Name.Boot;
FDefaultLookup.Add('cn', FCN);
FDefaultLookup.Add('l', FL);
FDefaultLookup.Add('st', FST);
+ // Microsoft CertNameToStr emits S= for stateOrProvinceName (2.5.4.8); accept as parse alias.
+ FDefaultLookup.Add('s', FST);
FDefaultLookup.Add('sn', FSurname);
FDefaultLookup.Add('serialnumber', FSerialNumber);
FDefaultLookup.Add('street', FStreet);
@@ -6798,6 +6783,35 @@ class procedure TX509Name.Boot;
FDefaultLookup.Add('jurisdictionlocality', FJurisdictionL);
end;
+class destructor TX509Name.Destroy;
+begin
+ FDefaultSymbols.Free;
+ FRFC2253Symbols.Free;
+ FRFC1779Symbols.Free;
+ FDefaultLookup.Free;
+ FDefaultReverseLock.Free;
+end;
+
+class function TX509Name.GetDefaultReverse: Boolean;
+begin
+ FDefaultReverseLock.Acquire;
+ try
+ Result := FDefaultReverse;
+ finally
+ FDefaultReverseLock.Release;
+ end;
+end;
+
+class procedure TX509Name.SetDefaultReverse(const AValue: Boolean);
+begin
+ FDefaultReverseLock.Acquire;
+ try
+ FDefaultReverse := AValue;
+ finally
+ FDefaultReverseLock.Release;
+ end;
+end;
+
class function TX509Name.CreateDefaultConverter: IX509NameEntryConverter;
begin
Result := TX509DefaultEntryConverter.Create();
@@ -8023,6 +8037,12 @@ constructor TIssuingDistributionPoint.Create(const ADistributionPoint: IDistribu
FSeq := TDerSequence.Create(LV);
end;
+constructor TIssuingDistributionPoint.Create(const ADistributionPoint: IDistributionPointName;
+ AIndirectCRL, AOnlyContainsAttributeCerts: Boolean);
+begin
+ Create(ADistributionPoint, False, False, nil, AIndirectCRL, AOnlyContainsAttributeCerts);
+end;
+
constructor TIssuingDistributionPoint.Create(const ASeq: IAsn1Sequence);
var
LCount, LPos: Int32;
diff --git a/CryptoLib/src/Asn1/X509/ClpX509ObjectIdentifiers.pas b/CryptoLib/src/Asn1/X509/ClpX509ObjectIdentifiers.pas
index 7672309b..be8900c0 100644
--- a/CryptoLib/src/Asn1/X509/ClpX509ObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/X509/ClpX509ObjectIdentifiers.pas
@@ -89,9 +89,7 @@ TX509ObjectIdentifiers = class abstract(TObject)
class function GetIdADOcsp: IDerObjectIdentifier; static; inline;
class function GetIdADCAIssuers: IDerObjectIdentifier; static; inline;
class function GetIdCe: IDerObjectIdentifier; static; inline;
-
- class procedure Boot(); static;
- class constructor X509ObjectIdentifiers();
+ class constructor Create();
public
// Attribute types
@@ -140,7 +138,7 @@ implementation
{ TX509ObjectIdentifiers }
-class procedure TX509ObjectIdentifiers.Boot;
+class constructor TX509ObjectIdentifiers.Create;
begin
// Base attribute type
FAttributeType := TDerObjectIdentifier.Create(AttributeType);
@@ -187,11 +185,6 @@ class procedure TX509ObjectIdentifiers.Boot;
FIdCe := TDerObjectIdentifier.Create('2.5.29');
end;
-class constructor TX509ObjectIdentifiers.X509ObjectIdentifiers;
-begin
- TX509ObjectIdentifiers.Boot();
-end;
-
class function TX509ObjectIdentifiers.GetAttributeType: IDerObjectIdentifier;
begin
Result := FAttributeType;
diff --git a/CryptoLib/src/Asn1/X509/ClpX509SignatureUtilities.pas b/CryptoLib/src/Asn1/X509/ClpX509SignatureUtilities.pas
index 495145c9..3a5aea57 100644
--- a/CryptoLib/src/Asn1/X509/ClpX509SignatureUtilities.pas
+++ b/CryptoLib/src/Asn1/X509/ClpX509SignatureUtilities.pas
@@ -63,7 +63,6 @@ TX509SignatureUtilities = class sealed(TObject)
class procedure AddAlgorithm(const AName: String; const AOid: IDerObjectIdentifier; AIsNoParams: Boolean); static;
class procedure AddNoParams(const AOid: IDerObjectIdentifier); static;
class function CreatePssParams(const ADigAlgID: IAlgorithmIdentifier; ASaltSize: Int32): IRsassaPssParameters; static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -80,18 +79,6 @@ implementation
{ TX509SignatureUtilities }
class constructor TX509SignatureUtilities.Create;
-begin
- Boot;
-end;
-
-class destructor TX509SignatureUtilities.Destroy;
-begin
- FAlgorithms.Free;
- FExParams.Free;
- FNoParams.Free;
-end;
-
-class procedure TX509SignatureUtilities.Boot;
var
LSha1AlgId, LSha224AlgId, LSha256AlgId, LSha384AlgId, LSha512AlgId: IAlgorithmIdentifier;
begin
@@ -303,6 +290,13 @@ class procedure TX509SignatureUtilities.Boot;
AddAlgorithm('Ed448', TEdECObjectIdentifiers.IdEd448, True);
end;
+class destructor TX509SignatureUtilities.Destroy;
+begin
+ FAlgorithms.Free;
+ FExParams.Free;
+ FNoParams.Free;
+end;
+
class function TX509SignatureUtilities.GetDigestName(const ADigestAlgOid: IDerObjectIdentifier): String;
begin
if TPkcsObjectIdentifiers.MD5.Equals(ADigestAlgOid) then
@@ -452,7 +446,7 @@ class function TX509SignatureUtilities.CreatePssParams(const ADigAlgID: IAlgorit
begin
LHashAlgId := ADigAlgID;
LMgfAlgId := TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdMgf1, LHashAlgId);
- LSaltLength := TDerInteger.Create(ASaltSize);
+ LSaltLength := TDerInteger.ValueOf(ASaltSize);
Result := TRsassaPssParameters.Create(LHashAlgId, LMgfAlgId, LSaltLength, TRsassaPssParameters.DefaultTrailerField);
end;
diff --git a/CryptoLib/src/Asn1/X9/ClpX962NamedCurves.pas b/CryptoLib/src/Asn1/X9/ClpX962NamedCurves.pas
index 288a21e7..4065d1d2 100644
--- a/CryptoLib/src/Asn1/X9/ClpX962NamedCurves.pas
+++ b/CryptoLib/src/Asn1/X9/ClpX962NamedCurves.pas
@@ -56,10 +56,8 @@ TX962NamedCurves = class sealed(TObject)
class procedure DefineCurve(const AName: String;
const AOid: IDerObjectIdentifier;
const AHolder: IX9ECParametersHolder); static;
-
- class procedure Boot; static;
- class constructor CreateX962NamedCurves;
- class destructor DestroyX962NamedCurves;
+ class constructor Create;
+ class destructor Destroy;
public
class function GetByName(const AName: String): IX9ECParameters;
@@ -273,7 +271,7 @@ class procedure TX962NamedCurves.DefineCurve(const AName: String;
FObjIds.Add(LName, AOid);
end;
-class procedure TX962NamedCurves.Boot;
+class constructor TX962NamedCurves.Create;
begin
FObjIds := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FCurves := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
@@ -304,12 +302,7 @@ class procedure TX962NamedCurves.Boot;
DefineCurve('c2tnb431r1', TX9ObjectIdentifiers.C2Tnb431r1, TC2tnb431r1Holder.Instance);
end;
-class constructor TX962NamedCurves.CreateX962NamedCurves;
-begin
- Boot;
-end;
-
-class destructor TX962NamedCurves.DestroyX962NamedCurves;
+class destructor TX962NamedCurves.Destroy;
begin
FObjIds.Free;
FCurves.Free;
diff --git a/CryptoLib/src/Asn1/X9/ClpX9ECAsn1Objects.pas b/CryptoLib/src/Asn1/X9/ClpX9ECAsn1Objects.pas
index c0a36adb..30e16f70 100644
--- a/CryptoLib/src/Asn1/X9/ClpX9ECAsn1Objects.pas
+++ b/CryptoLib/src/Asn1/X9/ClpX9ECAsn1Objects.pas
@@ -316,6 +316,7 @@ TX9ECParameters = class(TAsn1Encodable, IX9ECParameters)
/// Get tagged X9ECParameters.
///
class function GetTagged(const ATaggedObject: IAsn1TaggedObject; ADeclaredExplicit: Boolean): IX9ECParameters; static;
+ class function FromSequence(const ASeq: IAsn1Sequence): IX9ECParameters; static;
constructor Create(const ACurve: IECCurve; const AG: IX9ECPoint;
const AN: TBigInteger); overload;
@@ -720,7 +721,7 @@ class function TX9ECParameters.GetInstance(AObj: TObject): IX9ECParameters;
if Supports(AObj, IX9ECParameters, Result) then
Exit;
- Result := TX9ECParameters.Create(TAsn1Sequence.GetInstance(AObj));
+ Result := FromSequence(TAsn1Sequence.GetInstance(AObj));
end;
class function TX9ECParameters.GetInstance(const AObj: IAsn1Convertible): IX9ECParameters;
@@ -734,18 +735,18 @@ class function TX9ECParameters.GetInstance(const AObj: IAsn1Convertible): IX9ECP
if Supports(AObj, IX9ECParameters, Result) then
Exit;
- Result := TX9ECParameters.Create(TAsn1Sequence.GetInstance(AObj));
+ Result := FromSequence(TAsn1Sequence.GetInstance(AObj));
end;
class function TX9ECParameters.GetInstance(const AEncoded: TCryptoLibByteArray): IX9ECParameters;
begin
- Result := TX9ECParameters.Create(TAsn1Sequence.GetInstance(AEncoded));
+ Result := FromSequence(TAsn1Sequence.GetInstance(AEncoded));
end;
class function TX9ECParameters.GetInstance(const AObj: IAsn1TaggedObject;
AExplicitly: Boolean): IX9ECParameters;
begin
- Result := TX9ECParameters.Create(TAsn1Sequence.GetInstance(AObj, AExplicitly));
+ Result := FromSequence(TAsn1Sequence.GetInstance(AObj, AExplicitly));
end;
class function TX9ECParameters.GetOptional(const AElement: IAsn1Encodable): IX9ECParameters;
@@ -760,7 +761,7 @@ class function TX9ECParameters.GetOptional(const AElement: IAsn1Encodable): IX9E
LSequence := TAsn1Sequence.GetOptional(AElement);
if LSequence <> nil then
- Result := TX9ECParameters.Create(LSequence)
+ Result := FromSequence(LSequence)
else
Result := nil;
end;
@@ -768,7 +769,7 @@ class function TX9ECParameters.GetOptional(const AElement: IAsn1Encodable): IX9E
class function TX9ECParameters.GetTagged(const ATaggedObject: IAsn1TaggedObject;
ADeclaredExplicit: Boolean): IX9ECParameters;
begin
- Result := TX9ECParameters.Create(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
+ Result := FromSequence(TAsn1Sequence.GetTagged(ATaggedObject, ADeclaredExplicit));
end;
class function TX9ECParameters.ReadOptionalCofactor(AElement: IAsn1Encodable): TBigInteger;
@@ -782,6 +783,11 @@ class function TX9ECParameters.ReadOptionalCofactor(AElement: IAsn1Encodable): T
Result := TBigInteger.GetDefault;
end;
+class function TX9ECParameters.FromSequence(const ASeq: IAsn1Sequence): IX9ECParameters;
+begin
+ Result := TX9ECParameters.Create(ASeq);
+end;
+
constructor TX9ECParameters.Create(const ASeq: IAsn1Sequence);
var
LCount, LPos: Int32;
diff --git a/CryptoLib/src/Asn1/X9/ClpX9ObjectIdentifiers.pas b/CryptoLib/src/Asn1/X9/ClpX9ObjectIdentifiers.pas
index 90597e8b..30b174ff 100644
--- a/CryptoLib/src/Asn1/X9/ClpX9ObjectIdentifiers.pas
+++ b/CryptoLib/src/Asn1/X9/ClpX9ObjectIdentifiers.pas
@@ -29,7 +29,6 @@ interface
TX9ObjectIdentifiers = class abstract(TObject)
strict private
class var
- FIsBooted: Boolean;
FAnsiX9_62, FIdFieldType, FPrimeField, FCharacteristicTwoField, FGNBasis,
FTPBasis, FPPBasis, FIdEcSigType, FECDsaWithSha1, FIdPublicKeyType,
FIdECPublicKey, FECDsaWithSha2, FECDsaWithSha224, FECDsaWithSha256,
@@ -172,8 +171,6 @@ TX9ObjectIdentifiers = class abstract(TObject)
class property DHHybridOneFlow: IDerObjectIdentifier read GetDHHybridOneFlow;
class property Mqv2: IDerObjectIdentifier read GetMqv2;
class property Mqv1: IDerObjectIdentifier read GetMqv1;
-
- class procedure Boot; static;
end;
implementation
@@ -182,80 +179,70 @@ implementation
class constructor TX9ObjectIdentifiers.Create;
begin
- Boot;
-end;
-
-class procedure TX9ObjectIdentifiers.Boot;
-begin
- if not FIsBooted then
- begin
- FAnsiX9_62 := TDerObjectIdentifier.Create('1.2.840.10045');
- FIdFieldType := FAnsiX9_62.Branch('1');
- FPrimeField := FIdFieldType.Branch('1');
- FCharacteristicTwoField := FIdFieldType.Branch('2');
- FGNBasis := FCharacteristicTwoField.Branch('3.1');
- FTPBasis := FCharacteristicTwoField.Branch('3.2');
- FPPBasis := FCharacteristicTwoField.Branch('3.3');
- FIdEcSigType := FAnsiX9_62.Branch('4');
- FECDsaWithSha1 := FIdEcSigType.Branch('1');
- FIdPublicKeyType := FAnsiX9_62.Branch('2');
- FIdECPublicKey := FIdPublicKeyType.Branch('1');
- FECDsaWithSha2 := FIdEcSigType.Branch('3');
- FECDsaWithSha224 := FECDsaWithSha2.Branch('1');
- FECDsaWithSha256 := FECDsaWithSha2.Branch('2');
- FECDsaWithSha384 := FECDsaWithSha2.Branch('3');
- FECDsaWithSha512 := FECDsaWithSha2.Branch('4');
- FEllipticCurve := FAnsiX9_62.Branch('3');
- FCTwoCurve := FEllipticCurve.Branch('0');
- FC2Pnb163v1 := FCTwoCurve.Branch('1');
- FC2Pnb163v2 := FCTwoCurve.Branch('2');
- FC2Pnb163v3 := FCTwoCurve.Branch('3');
- FC2Pnb176w1 := FCTwoCurve.Branch('4');
- FC2Tnb191v1 := FCTwoCurve.Branch('5');
- FC2Tnb191v2 := FCTwoCurve.Branch('6');
- FC2Tnb191v3 := FCTwoCurve.Branch('7');
- FC2Onb191v4 := FCTwoCurve.Branch('8');
- FC2Onb191v5 := FCTwoCurve.Branch('9');
- FC2Pnb208w1 := FCTwoCurve.Branch('10');
- FC2Tnb239v1 := FCTwoCurve.Branch('11');
- FC2Tnb239v2 := FCTwoCurve.Branch('12');
- FC2Tnb239v3 := FCTwoCurve.Branch('13');
- FC2Onb239v4 := FCTwoCurve.Branch('14');
- FC2Onb239v5 := FCTwoCurve.Branch('15');
- FC2Pnb272w1 := FCTwoCurve.Branch('16');
- FC2Pnb304w1 := FCTwoCurve.Branch('17');
- FC2Tnb359v1 := FCTwoCurve.Branch('18');
- FC2Pnb368w1 := FCTwoCurve.Branch('19');
- FC2Tnb431r1 := FCTwoCurve.Branch('20');
- FPrimeCurve := FEllipticCurve.Branch('1');
- FPrime192v1 := FPrimeCurve.Branch('1');
- FPrime192v2 := FPrimeCurve.Branch('2');
- FPrime192v3 := FPrimeCurve.Branch('3');
- FPrime239v1 := FPrimeCurve.Branch('4');
- FPrime239v2 := FPrimeCurve.Branch('5');
- FPrime239v3 := FPrimeCurve.Branch('6');
- FPrime256v1 := FPrimeCurve.Branch('7');
- FIdDsa := TDerObjectIdentifier.Create('1.2.840.10040.4.1');
- FIdDsaWithSha1 := TDerObjectIdentifier.Create('1.2.840.10040.4.3');
- // TODO Seems this ought to be 1.3.133.16.840.9.63.0, but may be in common use
- FX9x63Scheme := TDerObjectIdentifier.Create('1.3.133.16.840.63.0');
- FDHSinglePassStdDHSha1KdfScheme := FX9x63Scheme.Branch('2');
- FDHSinglePassCofactorDHSha1KdfScheme := FX9x63Scheme.Branch('3');
- FMqvSinglePassSha1KdfScheme := FX9x63Scheme.Branch('16');
- FAnsiX9_42 := TDerObjectIdentifier.Create('1.2.840.10046');
- FDHPublicNumber := FAnsiX9_42.Branch('2.1');
- FX9x42Schemes := FAnsiX9_42.Branch('2.3');
- FDHStatic := FX9x42Schemes.Branch('1');
- FDHEphem := FX9x42Schemes.Branch('2');
- FDHOneFlow := FX9x42Schemes.Branch('3');
- FDHHybrid1 := FX9x42Schemes.Branch('4');
- FDHHybrid2 := FX9x42Schemes.Branch('5');
- FDHHybridOneFlow := FX9x42Schemes.Branch('6');
- FMqv2 := FX9x42Schemes.Branch('7');
- FMqv1 := FX9x42Schemes.Branch('8');
-
- FIsBooted := True;
- end;
+ FAnsiX9_62 := TDerObjectIdentifier.Create('1.2.840.10045');
+ FIdFieldType := FAnsiX9_62.Branch('1');
+ FPrimeField := FIdFieldType.Branch('1');
+ FCharacteristicTwoField := FIdFieldType.Branch('2');
+ FGNBasis := FCharacteristicTwoField.Branch('3.1');
+ FTPBasis := FCharacteristicTwoField.Branch('3.2');
+ FPPBasis := FCharacteristicTwoField.Branch('3.3');
+ FIdEcSigType := FAnsiX9_62.Branch('4');
+ FECDsaWithSha1 := FIdEcSigType.Branch('1');
+ FIdPublicKeyType := FAnsiX9_62.Branch('2');
+ FIdECPublicKey := FIdPublicKeyType.Branch('1');
+ FECDsaWithSha2 := FIdEcSigType.Branch('3');
+ FECDsaWithSha224 := FECDsaWithSha2.Branch('1');
+ FECDsaWithSha256 := FECDsaWithSha2.Branch('2');
+ FECDsaWithSha384 := FECDsaWithSha2.Branch('3');
+ FECDsaWithSha512 := FECDsaWithSha2.Branch('4');
+ FEllipticCurve := FAnsiX9_62.Branch('3');
+ FCTwoCurve := FEllipticCurve.Branch('0');
+ FC2Pnb163v1 := FCTwoCurve.Branch('1');
+ FC2Pnb163v2 := FCTwoCurve.Branch('2');
+ FC2Pnb163v3 := FCTwoCurve.Branch('3');
+ FC2Pnb176w1 := FCTwoCurve.Branch('4');
+ FC2Tnb191v1 := FCTwoCurve.Branch('5');
+ FC2Tnb191v2 := FCTwoCurve.Branch('6');
+ FC2Tnb191v3 := FCTwoCurve.Branch('7');
+ FC2Onb191v4 := FCTwoCurve.Branch('8');
+ FC2Onb191v5 := FCTwoCurve.Branch('9');
+ FC2Pnb208w1 := FCTwoCurve.Branch('10');
+ FC2Tnb239v1 := FCTwoCurve.Branch('11');
+ FC2Tnb239v2 := FCTwoCurve.Branch('12');
+ FC2Tnb239v3 := FCTwoCurve.Branch('13');
+ FC2Onb239v4 := FCTwoCurve.Branch('14');
+ FC2Onb239v5 := FCTwoCurve.Branch('15');
+ FC2Pnb272w1 := FCTwoCurve.Branch('16');
+ FC2Pnb304w1 := FCTwoCurve.Branch('17');
+ FC2Tnb359v1 := FCTwoCurve.Branch('18');
+ FC2Pnb368w1 := FCTwoCurve.Branch('19');
+ FC2Tnb431r1 := FCTwoCurve.Branch('20');
+ FPrimeCurve := FEllipticCurve.Branch('1');
+ FPrime192v1 := FPrimeCurve.Branch('1');
+ FPrime192v2 := FPrimeCurve.Branch('2');
+ FPrime192v3 := FPrimeCurve.Branch('3');
+ FPrime239v1 := FPrimeCurve.Branch('4');
+ FPrime239v2 := FPrimeCurve.Branch('5');
+ FPrime239v3 := FPrimeCurve.Branch('6');
+ FPrime256v1 := FPrimeCurve.Branch('7');
+ FIdDsa := TDerObjectIdentifier.Create('1.2.840.10040.4.1');
+ FIdDsaWithSha1 := TDerObjectIdentifier.Create('1.2.840.10040.4.3');
+ // TODO Seems this ought to be 1.3.133.16.840.9.63.0, but may be in common use
+ FX9x63Scheme := TDerObjectIdentifier.Create('1.3.133.16.840.63.0');
+ FDHSinglePassStdDHSha1KdfScheme := FX9x63Scheme.Branch('2');
+ FDHSinglePassCofactorDHSha1KdfScheme := FX9x63Scheme.Branch('3');
+ FMqvSinglePassSha1KdfScheme := FX9x63Scheme.Branch('16');
+ FAnsiX9_42 := TDerObjectIdentifier.Create('1.2.840.10046');
+ FDHPublicNumber := FAnsiX9_42.Branch('2.1');
+ FX9x42Schemes := FAnsiX9_42.Branch('2.3');
+ FDHStatic := FX9x42Schemes.Branch('1');
+ FDHEphem := FX9x42Schemes.Branch('2');
+ FDHOneFlow := FX9x42Schemes.Branch('3');
+ FDHHybrid1 := FX9x42Schemes.Branch('4');
+ FDHHybrid2 := FX9x42Schemes.Branch('5');
+ FDHHybridOneFlow := FX9x42Schemes.Branch('6');
+ FMqv2 := FX9x42Schemes.Branch('7');
+ FMqv1 := FX9x42Schemes.Branch('8');
end;
class function TX9ObjectIdentifiers.GetAnsiX9_42: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Crypto/Agreements/ClpAgreementUtilities.pas b/CryptoLib/src/Crypto/Agreements/ClpAgreementUtilities.pas
index 1d01a39c..6d89bf63 100644
--- a/CryptoLib/src/Crypto/Agreements/ClpAgreementUtilities.pas
+++ b/CryptoLib/src/Crypto/Agreements/ClpAgreementUtilities.pas
@@ -76,7 +76,6 @@ TAgreementUtilities = class sealed(TObject)
class function GetBasicAgreementWithKdfForMechanism(const AMechanism, AWrapAlgorithm: String): IBasicAgreement; static;
class function GetRawAgreementForMechanism(const AMechanism: String): IRawAgreement; static;
class function CreateECDHKekGenerator(const ADigestName: String): IDerivationFunction; static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
public
@@ -94,7 +93,7 @@ implementation
{ TAgreementUtilities }
-class procedure TAgreementUtilities.Boot;
+class constructor TAgreementUtilities.Create;
begin
FAlgorithmMap := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FAlgorithmMap.Add('DIFFIEHELLMAN', 'DH');
@@ -122,11 +121,6 @@ class procedure TAgreementUtilities.Boot;
FAlgorithmOidMap.AddOrSetValue(TEdECObjectIdentifiers.IdX448, 'X448');
end;
-class constructor TAgreementUtilities.Create;
-begin
- Boot;
-end;
-
class destructor TAgreementUtilities.Destroy;
begin
FAlgorithmMap.Free;
diff --git a/CryptoLib/src/Crypto/Agreements/ClpX25519Agreement.pas b/CryptoLib/src/Crypto/Agreements/ClpX25519Agreement.pas
index 2183652d..b84bfe9d 100644
--- a/CryptoLib/src/Crypto/Agreements/ClpX25519Agreement.pas
+++ b/CryptoLib/src/Crypto/Agreements/ClpX25519Agreement.pas
@@ -34,6 +34,11 @@ interface
'The Init Parameter does not Contain the Private Key';
type
+ ///
+ /// X25519 (RFC 7748) Diffie-Hellman raw agreement. Init takes the local
+ /// ; CalculateAgreement writes the 32-byte shared secret
+ /// derived against the peer's .
+ ///
TX25519Agreement = class sealed(TInterfacedObject, IX25519Agreement,
IRawAgreement)
@@ -45,11 +50,28 @@ TX25519Agreement = class sealed(TInterfacedObject, IX25519Agreement,
public
+ /// Capture the local private key used for subsequent agreements.
+ ///
+ /// If is not an
+ /// .
+ ///
procedure Init(const AParameters: ICipherParameters);
+ ///
+ /// Perform the agreement against and write the shared secret into
+ /// starting at .
+ ///
+ ///
+ /// If is not an
+ /// .
+ ///
+ ///
+ /// If the agreement produces an all-zero secret (degenerate peer key).
+ ///
procedure CalculateAgreement(const APublicKey: ICipherParameters;
const ABuf: TCryptoLibByteArray; AOff: Int32);
+ /// Length in bytes of the shared secret produced by the agreement (32).
property AgreementSize: Int32 read GetAgreementSize;
end;
diff --git a/CryptoLib/src/Crypto/Agreements/ClpX448Agreement.pas b/CryptoLib/src/Crypto/Agreements/ClpX448Agreement.pas
index b60fec61..71a63dd6 100644
--- a/CryptoLib/src/Crypto/Agreements/ClpX448Agreement.pas
+++ b/CryptoLib/src/Crypto/Agreements/ClpX448Agreement.pas
@@ -34,6 +34,11 @@ interface
'The Init Parameter does not Contain the Private Key';
type
+ ///
+ /// X448 (RFC 7748) Diffie-Hellman raw agreement. Init takes the local
+ /// ; CalculateAgreement writes the 56-byte shared secret
+ /// derived against the peer's .
+ ///
TX448Agreement = class sealed(TInterfacedObject, IX448Agreement,
IRawAgreement)
@@ -45,11 +50,28 @@ TX448Agreement = class sealed(TInterfacedObject, IX448Agreement,
public
+ /// Capture the local private key used for subsequent agreements.
+ ///
+ /// If is not an
+ /// .
+ ///
procedure Init(const AParameters: ICipherParameters);
+ ///
+ /// Perform the agreement against and write the shared secret into
+ /// starting at .
+ ///
+ ///
+ /// If is not an
+ /// .
+ ///
+ ///
+ /// If the agreement produces an all-zero secret (degenerate peer key).
+ ///
procedure CalculateAgreement(const APublicKey: ICipherParameters;
const ABuf: TCryptoLibByteArray; AOff: Int32);
+ /// Length in bytes of the shared secret produced by the agreement (56).
property AgreementSize: Int32 read GetAgreementSize;
end;
diff --git a/CryptoLib/src/Crypto/ClpCipherUtilities.pas b/CryptoLib/src/Crypto/ClpCipherUtilities.pas
index 7be7acfa..bfd39e96 100644
--- a/CryptoLib/src/Crypto/ClpCipherUtilities.pas
+++ b/CryptoLib/src/Crypto/ClpCipherUtilities.pas
@@ -200,8 +200,6 @@ TCipherUtilities = class sealed(TObject)
class function GetMechanism(const AAlgorithm: String): String; static;
class function GetCipherForMechanism(const AMechanism: String): IBufferedCipher; static;
class function CreateBlockCipher(ACipherAlgorithm: TCipherAlgorithm): IBlockCipher; static;
-
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -238,14 +236,11 @@ implementation
{ TCipherUtilities }
-class procedure TCipherUtilities.Boot;
+class constructor TCipherUtilities.Create;
begin
FAlgorithmMap := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FAlgorithmOidMap := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
- TNistObjectIdentifiers.Boot;
- TPkcsObjectIdentifiers.Boot;
-
FAlgorithmOidMap.AddOrSetValue(TNistObjectIdentifiers.IdAes128Cbc, 'AES/CBC/PKCS7PADDING');
FAlgorithmOidMap.AddOrSetValue(TNistObjectIdentifiers.IdAes192Cbc, 'AES/CBC/PKCS7PADDING');
FAlgorithmOidMap.AddOrSetValue(TNistObjectIdentifiers.IdAes256Cbc, 'AES/CBC/PKCS7PADDING');
@@ -296,11 +291,6 @@ class procedure TCipherUtilities.Boot;
FAlgorithmOidMap.AddOrSetValue(TPkcsObjectIdentifiers.IdAlgAeadChaCha20Poly1305, 'CHACHA20-POLY1305');
end;
-class constructor TCipherUtilities.Create;
-begin
- Boot;
-end;
-
class destructor TCipherUtilities.Destroy;
begin
FAlgorithmMap.Free;
diff --git a/CryptoLib/src/Crypto/ClpPbeUtilities.pas b/CryptoLib/src/Crypto/ClpPbeUtilities.pas
index 468fe3b7..f43cce97 100644
--- a/CryptoLib/src/Crypto/ClpPbeUtilities.pas
+++ b/CryptoLib/src/Crypto/ClpPbeUtilities.pas
@@ -73,14 +73,12 @@ TPbeUtilities = class sealed(TObject)
Pkcs12 = 'Pkcs12';
OpenSsl = 'OpenSsl';
class var
- FIsBooted: Boolean;
FAlgorithms: TDictionary;
FAlgorithmType: TDictionary;
FOids: TDictionary;
class constructor Create;
class destructor Destroy;
strict private
- class procedure Boot; static;
class function MakePbeGenerator(const AType: String; const ADigest: IDigest;
const AKey: TCryptoLibByteArray; const ASalt: TCryptoLibByteArray;
AIterationCount: Int32): IPbeParametersGenerator; static;
@@ -168,15 +166,7 @@ implementation
class constructor TPbeUtilities.Create;
begin
- Boot;
-end;
-
-class procedure TPbeUtilities.Boot;
-begin
- if FIsBooted then
- Exit;
-
- FAlgorithms := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
+FAlgorithms := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FAlgorithmType := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FOids := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
@@ -267,8 +257,6 @@ class procedure TPbeUtilities.Boot;
FOids.AddOrSetValue('PBEwithHmacRipeMD160', TTeleTrusTObjectIdentifiers.RipeMD160);
FOids.AddOrSetValue('PBEwithHmacRipeMD256', TTeleTrusTObjectIdentifiers.RipeMD256);
FOids.AddOrSetValue('Pkcs5scheme2', TPkcsObjectIdentifiers.IdPbeS2);
-
- FIsBooted := True;
end;
class destructor TPbeUtilities.Destroy;
diff --git a/CryptoLib/src/Crypto/ClpWrapperUtilities.pas b/CryptoLib/src/Crypto/ClpWrapperUtilities.pas
index 1acdb7b3..23c8f8c9 100644
--- a/CryptoLib/src/Crypto/ClpWrapperUtilities.pas
+++ b/CryptoLib/src/Crypto/ClpWrapperUtilities.pas
@@ -69,8 +69,6 @@ TBufferedCipherWrapper = class(TInterfacedObject, IWrapper)
class var
FAlgorithms: TDictionary;
-
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -86,21 +84,9 @@ implementation
{ TWrapperUtilities }
class constructor TWrapperUtilities.Create;
-begin
- Boot;
-end;
-
-class destructor TWrapperUtilities.Destroy;
-begin
- FAlgorithms.Free;
-end;
-
-class procedure TWrapperUtilities.Boot;
begin
FAlgorithms := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
- TNistObjectIdentifiers.Boot;
-
FAlgorithms.AddOrSetValue('AESKW', 'AESWRAP');
FAlgorithms.AddOrSetValue(TNistObjectIdentifiers.IdAes128Wrap.Id, 'AESWRAP');
FAlgorithms.AddOrSetValue(TNistObjectIdentifiers.IdAes192Wrap.Id, 'AESWRAP');
@@ -113,6 +99,11 @@ class procedure TWrapperUtilities.Boot;
FAlgorithms.AddOrSetValue('AESRFC5649WRAP', 'AESWRAPPAD');
end;
+class destructor TWrapperUtilities.Destroy;
+begin
+ FAlgorithms.Free;
+end;
+
class function TWrapperUtilities.GetWrapper(
const AOid: IDerObjectIdentifier): IWrapper;
begin
diff --git a/CryptoLib/src/Crypto/Digests/ClpDigestUtilities.pas b/CryptoLib/src/Crypto/Digests/ClpDigestUtilities.pas
index b88cebcb..d79779ca 100644
--- a/CryptoLib/src/Crypto/Digests/ClpDigestUtilities.pas
+++ b/CryptoLib/src/Crypto/Digests/ClpDigestUtilities.pas
@@ -113,7 +113,6 @@ TDigestUtilities = class sealed(TObject)
class function GetMechanism(const AAlgorithm: String): String; static;
class function GetDigestForMechanism(const AMechanism: String): IDigest; static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -327,19 +326,62 @@ class function TDigestUtilities.GetDigestForMechanism(const AMechanism: String):
end;
end;
-class procedure TDigestUtilities.Boot;
+class function TDigestUtilities.DoFinal(const ADigest: IDigest)
+ : TCryptoLibByteArray;
+begin
+ System.SetLength(Result, ADigest.GetDigestSize());
+ ADigest.DoFinal(Result, 0);
+end;
+
+class function TDigestUtilities.DoFinal(const ADigest: IDigest;
+ const AInput: TCryptoLibByteArray): TCryptoLibByteArray;
+begin
+ ADigest.BlockUpdate(AInput, 0, System.Length(AInput));
+ Result := DoFinal(ADigest);
+end;
+
+class function TDigestUtilities.DoFinal(const ADigest: IDigest;
+ const AInput: TCryptoLibByteArray; AOffset, ALength: Int32): TCryptoLibByteArray;
+begin
+ ADigest.BlockUpdate(AInput, AOffset, ALength);
+ Result := DoFinal(ADigest);
+end;
+
+class function TDigestUtilities.CalculateDigest(const AOid: IDerObjectIdentifier;
+ const AInput: TCryptoLibByteArray): TCryptoLibByteArray;
+var
+ LDigest: IDigest;
+begin
+ LDigest := GetDigest(AOid);
+ Result := DoFinal(LDigest, AInput);
+end;
+
+class function TDigestUtilities.CalculateDigest(const AAlgorithm: String;
+ const AInput: TCryptoLibByteArray): TCryptoLibByteArray;
+var
+ LDigest: IDigest;
+begin
+ LDigest := GetDigest(AAlgorithm);
+ LDigest.BlockUpdate(AInput, 0, System.Length(AInput));
+ Result := DoFinal(LDigest);
+end;
+
+class function TDigestUtilities.CalculateDigest(const AAlgorithm: String;
+ const AInput: TCryptoLibByteArray; AOffset, ALength: Int32): TCryptoLibByteArray;
+var
+ LDigest: IDigest;
+begin
+ LDigest := GetDigest(AAlgorithm);
+ LDigest.BlockUpdate(AInput, AOffset, ALength);
+ Result := DoFinal(LDigest);
+end;
+
+class constructor TDigestUtilities.Create;
begin
FAlgorithmMap := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FAlgorithmOidMap := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
FOids := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
- TPkcsObjectIdentifiers.Boot;
- TOiwObjectIdentifiers.Boot;
- TMiscObjectIdentifiers.Boot;
- TTeleTrusTObjectIdentifiers.Boot;
- TCryptoProObjectIdentifiers.Boot;
- TRosstandartObjectIdentifiers.Boot;
-
// MD
FAlgorithmOidMap.AddOrSetValue(TPkcsObjectIdentifiers.MD2, 'MD2');
FAlgorithmOidMap.AddOrSetValue(TPkcsObjectIdentifiers.MD4, 'MD4');
@@ -440,12 +482,12 @@ class procedure TDigestUtilities.Boot;
// GOST 2012
FAlgorithmOidMap.AddOrSetValue(
- TRosstandartObjectIdentifiers.IdTc26Gost3411_12_256,
- 'GOST3411-2012-256'
+ TRosstandartObjectIdentifiers.IdTc26Gost3411_12_256,
+ 'GOST3411-2012-256'
);
FAlgorithmOidMap.AddOrSetValue(
- TRosstandartObjectIdentifiers.IdTc26Gost3411_12_512,
- 'GOST3411-2012-512'
+ TRosstandartObjectIdentifiers.IdTc26Gost3411_12_512,
+ 'GOST3411-2012-512'
);
// Reverse OID lookup
@@ -483,61 +525,6 @@ class procedure TDigestUtilities.Boot;
end;
-class function TDigestUtilities.DoFinal(const ADigest: IDigest)
- : TCryptoLibByteArray;
-begin
- System.SetLength(Result, ADigest.GetDigestSize());
- ADigest.DoFinal(Result, 0);
-end;
-
-class function TDigestUtilities.DoFinal(const ADigest: IDigest;
- const AInput: TCryptoLibByteArray): TCryptoLibByteArray;
-begin
- ADigest.BlockUpdate(AInput, 0, System.Length(AInput));
- Result := DoFinal(ADigest);
-end;
-
-class function TDigestUtilities.DoFinal(const ADigest: IDigest;
- const AInput: TCryptoLibByteArray; AOffset, ALength: Int32): TCryptoLibByteArray;
-begin
- ADigest.BlockUpdate(AInput, AOffset, ALength);
- Result := DoFinal(ADigest);
-end;
-
-class function TDigestUtilities.CalculateDigest(const AOid: IDerObjectIdentifier;
- const AInput: TCryptoLibByteArray): TCryptoLibByteArray;
-var
- LDigest: IDigest;
-begin
- LDigest := GetDigest(AOid);
- Result := DoFinal(LDigest, AInput);
-end;
-
-class function TDigestUtilities.CalculateDigest(const AAlgorithm: String;
- const AInput: TCryptoLibByteArray): TCryptoLibByteArray;
-var
- LDigest: IDigest;
-begin
- LDigest := GetDigest(AAlgorithm);
- LDigest.BlockUpdate(AInput, 0, System.Length(AInput));
- Result := DoFinal(LDigest);
-end;
-
-class function TDigestUtilities.CalculateDigest(const AAlgorithm: String;
- const AInput: TCryptoLibByteArray; AOffset, ALength: Int32): TCryptoLibByteArray;
-var
- LDigest: IDigest;
-begin
- LDigest := GetDigest(AAlgorithm);
- LDigest.BlockUpdate(AInput, AOffset, ALength);
- Result := DoFinal(LDigest);
-end;
-
-class constructor TDigestUtilities.Create;
-begin
- Boot;
-end;
-
class destructor TDigestUtilities.Destroy;
begin
FAlgorithmMap.Free;
diff --git a/CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas b/CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas
index b273bbd3..5df99b16 100644
--- a/CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas
+++ b/CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas
@@ -70,9 +70,8 @@ TCustomNamedCurves = class sealed(TObject)
const AP: IGlvTypeBParameters): IECCurve; static; inline;
class function ConfigureBasepoint(const ACurve: IECCurve;
const AEncoding: String): IX9ECPoint; static;
- class procedure Boot; static;
- class constructor CreateCustomNamedCurves;
- class destructor DestroyCustomNamedCurves;
+ class constructor Create;
+ class destructor Destroy;
public
class function GetByName(const AName: String): IX9ECParameters; static; inline;
@@ -214,7 +213,7 @@ class function TCustomNamedCurves.GetNames: TCryptoLibStringArray;
Result := TCollectionUtilities.Keys(FObjIds);
end;
-class procedure TCustomNamedCurves.Boot;
+class constructor TCustomNamedCurves.Create;
begin
FObjIds := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FCurves := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
@@ -232,12 +231,7 @@ class procedure TCustomNamedCurves.Boot;
DefineCurveAlias('P-521', TSecObjectIdentifiers.SecP521r1);
end;
-class constructor TCustomNamedCurves.CreateCustomNamedCurves;
-begin
- Boot;
-end;
-
-class destructor TCustomNamedCurves.DestroyCustomNamedCurves;
+class destructor TCustomNamedCurves.Destroy;
begin
FObjIds.Free;
FCurves.Free;
diff --git a/CryptoLib/src/Crypto/Engines/ClpAesEngine.pas b/CryptoLib/src/Crypto/Engines/ClpAesEngine.pas
index 2c6778f8..fdda7450 100644
--- a/CryptoLib/src/Crypto/Engines/ClpAesEngine.pas
+++ b/CryptoLib/src/Crypto/Engines/ClpAesEngine.pas
@@ -311,7 +311,7 @@ class function TAesEngine.SubWord(AX: UInt32): UInt32;
procedure TAesEngine.DecryptBlock(const AKw: TCryptoLibUInt32Array;
var AC0, AC1, AC2, AC3: UInt32);
var
- LKw: PUInt32;
+ LKw: PCardinal;
LState: PByte;
LT0, LT1, LT2, LR0, LR1, LR2, LR3: UInt32;
LR, LRounds: Int32;
@@ -393,7 +393,7 @@ procedure TAesEngine.DecryptBlock(const AKw: TCryptoLibUInt32Array;
procedure TAesEngine.EncryptBlock(const AKw: TCryptoLibUInt32Array;
var AC0, AC1, AC2, AC3: UInt32);
var
- LKw: PUInt32;
+ LKw: PCardinal;
LState: PByte;
LT0, LT1, LT2, LR0, LR1, LR2, LR3: UInt32;
LR, LRounds: Int32;
diff --git a/CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas b/CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas
index e44147ba..9f88ae67 100644
--- a/CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas
+++ b/CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas
@@ -247,7 +247,7 @@ class function TAesLightEngine.Inv_Mcol(AX: UInt32): UInt32;
procedure TAesLightEngine.EncryptBlock(const AKw: TCryptoLibUInt32Array;
var AC0, AC1, AC2, AC3: UInt32);
var
- LKw: PUInt32;
+ LKw: PCardinal;
LT0, LT1, LT2, LR0, LR1, LR2, LR3: UInt32;
LR, LRounds: Int32;
begin
@@ -326,7 +326,7 @@ procedure TAesLightEngine.EncryptBlock(const AKw: TCryptoLibUInt32Array;
procedure TAesLightEngine.DecryptBlock(const AKw: TCryptoLibUInt32Array;
var AC0, AC1, AC2, AC3: UInt32);
var
- LKw: PUInt32;
+ LKw: PCardinal;
LT0, LT1, LT2, LR0, LR1, LR2, LR3: UInt32;
LR, LRounds: Int32;
begin
diff --git a/CryptoLib/src/Crypto/Engines/ClpChaCha7539Engine.pas b/CryptoLib/src/Crypto/Engines/ClpChaCha7539Engine.pas
index 76620834..3bea5197 100644
--- a/CryptoLib/src/Crypto/Engines/ClpChaCha7539Engine.pas
+++ b/CryptoLib/src/Crypto/Engines/ClpChaCha7539Engine.pas
@@ -30,7 +30,8 @@ interface
ClpPack,
ClpCryptoLibTypes,
ClpCpuFeatures,
- ClpSimdLevels;
+ ClpSimdLevels,
+ ClpByteUtilities;
resourcestring
SInvalidKeySize256 = '%s Requires 256 bit key';
@@ -229,12 +230,8 @@ procedure TChaCha7539Engine.DoFinal(const AInBuf: TCryptoLibByteArray;
AdvanceCounter();
LQ := AInLen shr 3;
- for LIdx := 0 to System.Pred(LQ) do
- begin
- PUInt64(PByte(@AOutBuf[AOutOff]) + (LIdx * 8))^ := PUInt64(
- PByte(@AInBuf[AInOff]) + (LIdx * 8))^ xor PUInt64(
- PByte(@FKeyStream[0]) + (LIdx * 8))^;
- end;
+ if LQ > 0 then
+ TByteUtilities.&Xor(LQ * 8, AInBuf, AInOff, FKeyStream, 0, AOutBuf, AOutOff);
for LIdx := (LQ * 8) to System.Pred(AInLen) do
begin
AOutBuf[AOutOff + LIdx] := Byte(
@@ -311,15 +308,12 @@ procedure TChaCha7539Engine.ProcessBytes(const AInBytes: TCryptoLibByteArray;
GenerateKeyStream(FKeyStream);
AdvanceCounter();
LTake := ALen;
- LInP := @AInBytes[AInOff];
- LOutP := @AOutBytes[AOutOff];
- LKeyP := @FKeyStream[0];
+ LInP := PByte(AInBytes) + AInOff;
+ LOutP := PByte(AOutBytes) + AOutOff;
+ LKeyP := PByte(FKeyStream);
LQ := LTake shr 3;
- for LIdx := 0 to System.Pred(LQ) do
- begin
- PUInt64(LOutP + (LIdx * 8))^ := PUInt64(LInP + (LIdx * 8))^ xor
- PUInt64(LKeyP + (LIdx * 8))^;
- end;
+ if LQ > 0 then
+ TByteUtilities.&Xor(LQ * 8, LInP, LKeyP, LOutP);
for LIdx := (LQ * 8) to System.Pred(LTake) do
begin
LOutP[LIdx] := LInP[LIdx] xor LKeyP[LIdx];
@@ -425,20 +419,15 @@ procedure TChaCha7539Engine.ImplProcessBlock(
const AInBuf: TCryptoLibByteArray; AInOff: Int32;
const AOutBuf: TCryptoLibByteArray; AOutOff: Int32);
var
- LIdx: Int32;
LInP, LOutP, LKeyP: PByte;
begin
TChaChaEngine.ChaChaCore(FRounds, FEngineState, FKeyStream);
AdvanceCounter();
- LInP := @AInBuf[AInOff];
- LKeyP := @FKeyStream[0];
- LOutP := @AOutBuf[AOutOff];
- for LIdx := 0 to 7 do
- begin
- PUInt64(LOutP + (LIdx * 8))^ := PUInt64(LInP + (LIdx * 8))^ xor
- PUInt64(LKeyP + (LIdx * 8))^;
- end;
+ LInP := PByte(AInBuf) + AInOff;
+ LKeyP := PByte(FKeyStream);
+ LOutP := PByte(AOutBuf) + AOutOff;
+ TByteUtilities.&Xor(64, LInP, LKeyP, LOutP);
end;
end.
diff --git a/CryptoLib/src/Crypto/Engines/ClpIesEngine.pas b/CryptoLib/src/Crypto/Engines/ClpIesEngine.pas
index 3c71c372..37f23f3f 100644
--- a/CryptoLib/src/Crypto/Engines/ClpIesEngine.pas
+++ b/CryptoLib/src/Crypto/Engines/ClpIesEngine.pas
@@ -209,7 +209,7 @@ function TIesEngine.GetLengthTag(const AP2: TCryptoLibByteArray)
System.SetLength(Result, 8);
if (AP2 <> nil) then
begin
- TPack.UInt64_To_BE(UInt64(System.Length(AP2) * 8), Result, 0);
+ TPack.UInt64_To_BE(UInt64(System.Length(AP2)) * UInt64(8), Result, 0);
end;
end;
diff --git a/CryptoLib/src/Crypto/Engines/ClpSalsa20Engine.pas b/CryptoLib/src/Crypto/Engines/ClpSalsa20Engine.pas
index 88732091..4cdfd3ec 100644
--- a/CryptoLib/src/Crypto/Engines/ClpSalsa20Engine.pas
+++ b/CryptoLib/src/Crypto/Engines/ClpSalsa20Engine.pas
@@ -32,6 +32,7 @@ interface
ClpPack,
ClpCpuFeatures,
ClpSimdLevels,
+ ClpByteUtilities,
ClpCryptoLibTypes;
resourcestring
@@ -329,20 +330,15 @@ procedure TSalsa20Engine.ImplProcessBlock(
const AInBytes: TCryptoLibByteArray; AInOff: Int32;
const AOutBytes: TCryptoLibByteArray; AOutOff: Int32);
var
- LIdx: Int32;
LInP, LOutP, LKeyP: PByte;
begin
AssertInitialisedAndBlockAligned;
GenerateKeyStream(FKeyStream);
AdvanceCounter();
- LInP := @AInBytes[AInOff];
- LOutP := @AOutBytes[AOutOff];
- LKeyP := @FKeyStream[0];
- for LIdx := 0 to 7 do
- begin
- PUInt64(LOutP + (LIdx * 8))^ := PUInt64(LInP + (LIdx * 8))^ xor
- PUInt64(LKeyP + (LIdx * 8))^;
- end;
+ LInP := PByte(AInBytes) + AInOff;
+ LOutP := PByte(AOutBytes) + AOutOff;
+ LKeyP := PByte(FKeyStream);
+ TByteUtilities.&Xor(64, LInP, LKeyP, LOutP);
end;
procedure TSalsa20Engine.ProcessBlocks2(
@@ -439,11 +435,8 @@ procedure TSalsa20Engine.ProcessBytes(const AInBytes: TCryptoLibByteArray;
LOutP := @AOutBytes[AOutOff];
LKeyP := @FKeyStream[0];
LQ := LTake shr 3;
- for LIdx := 0 to System.Pred(LQ) do
- begin
- PUInt64(LOutP + (LIdx * 8))^ := PUInt64(LInP + (LIdx * 8))^ xor
- PUInt64(LKeyP + (LIdx * 8))^;
- end;
+ if LQ > 0 then
+ TByteUtilities.&Xor(LQ * 8, LInP, LKeyP, LOutP);
for LIdx := (LQ * 8) to System.Pred(LTake) do
begin
LOutP[LIdx] := LInP[LIdx] xor LKeyP[LIdx];
diff --git a/CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas b/CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas
index 64438182..79fc41e8 100644
--- a/CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas
+++ b/CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas
@@ -42,15 +42,10 @@ TDHParametersHelper = class sealed(TObject)
FPrimeProducts: TCryptoLibInt32Array;
FPrimeLists: TCryptoLibMatrixInt32Array;
FBigPrimeProducts: TCryptoLibGenericArray;
- FIsBooted: Boolean;
-
class function ConstructBigPrimeProducts(const APrimeProducts
: TCryptoLibInt32Array): TCryptoLibGenericArray; static;
class function HasAnySmallFactorsSafe(const X: TBigInteger): Boolean; static;
-
- class procedure Boot(); static;
-
class constructor DHParametersHelper();
public
@@ -71,25 +66,15 @@ implementation
{ TDHParametersHelper }
-class procedure TDHParametersHelper.Boot;
-begin
- if not FIsBooted then
- begin
- FTwo := TBigInteger.Two;
- FTwelve := TBigInteger.ValueOf(12);
- FTwentyFour := TBigInteger.ValueOf(24);
-
- FPrimeLists := TBigInteger.primeLists;
- FPrimeProducts := TBigInteger.primeProducts;
- FBigPrimeProducts := ConstructBigPrimeProducts(FPrimeProducts);
-
- FIsBooted := True;
- end;
-end;
-
class constructor TDHParametersHelper.DHParametersHelper;
begin
- TDHParametersHelper.Boot;
+ FTwo := TBigInteger.Two;
+ FTwelve := TBigInteger.ValueOf(12);
+ FTwentyFour := TBigInteger.ValueOf(24);
+
+ FPrimeLists := TBigInteger.primeLists;
+ FPrimeProducts := TBigInteger.primeProducts;
+ FBigPrimeProducts := ConstructBigPrimeProducts(FPrimeProducts);
end;
class function TDHParametersHelper.ConstructBigPrimeProducts(const APrimeProducts
diff --git a/CryptoLib/src/Crypto/Generators/ClpEd25519Generators.pas b/CryptoLib/src/Crypto/Generators/ClpEd25519Generators.pas
index c3287c9c..612cc77b 100644
--- a/CryptoLib/src/Crypto/Generators/ClpEd25519Generators.pas
+++ b/CryptoLib/src/Crypto/Generators/ClpEd25519Generators.pas
@@ -31,13 +31,20 @@ interface
ClpIAsymmetricCipherKeyPairGenerator;
type
+ ///
+ /// Key-pair generator for Ed25519 (RFC 8032). Only the from the supplied
+ /// key-generation parameters is used; the 32-byte seed is drawn directly from it.
+ ///
TEd25519KeyPairGenerator = class(TInterfacedObject, IEd25519KeyPairGenerator,
IAsymmetricCipherKeyPairGenerator)
strict private
FRandom: ISecureRandom;
public
+ /// Construct an uninitialised generator; call before use.
constructor Create();
+ /// Capture the that will source the seed.
procedure Init(const AParameters: IKeyGenerationParameters);
+ /// Generate a fresh Ed25519 key pair.
function GenerateKeyPair(): IAsymmetricCipherKeyPair;
end;
diff --git a/CryptoLib/src/Crypto/Generators/ClpEd448Generators.pas b/CryptoLib/src/Crypto/Generators/ClpEd448Generators.pas
index e60c17ea..30309f85 100644
--- a/CryptoLib/src/Crypto/Generators/ClpEd448Generators.pas
+++ b/CryptoLib/src/Crypto/Generators/ClpEd448Generators.pas
@@ -31,12 +31,18 @@ interface
ClpIAsymmetricCipherKeyPairGenerator;
type
+ ///
+ /// Key-pair generator for Ed448 (RFC 8032). Only the from the supplied
+ /// key-generation parameters is used; the 57-byte seed is drawn directly from it.
+ ///
TEd448KeyPairGenerator = class sealed(TInterfacedObject,
IEd448KeyPairGenerator, IAsymmetricCipherKeyPairGenerator)
strict private
FRandom: ISecureRandom;
public
+ /// Capture the that will source the seed.
procedure Init(const AParameters: IKeyGenerationParameters);
+ /// Generate a fresh Ed448 key pair.
function GenerateKeyPair(): IAsymmetricCipherKeyPair;
end;
diff --git a/CryptoLib/src/Crypto/Generators/ClpGeneratorUtilities.pas b/CryptoLib/src/Crypto/Generators/ClpGeneratorUtilities.pas
index f7fc5c4d..ea4a0721 100644
--- a/CryptoLib/src/Crypto/Generators/ClpGeneratorUtilities.pas
+++ b/CryptoLib/src/Crypto/Generators/ClpGeneratorUtilities.pas
@@ -90,7 +90,6 @@ TGeneratorUtilities = class sealed(TObject)
class procedure AddKgAlgorithm(const ACanonicalName: String; const AAliases: array of String); static;
class procedure AddKpgAlgorithm(const ACanonicalName: String; const AAliases: array of String); static;
class procedure AddHMacKeyGenerator(const AAlgorithm: String; const AAliases: array of String); static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -179,38 +178,35 @@ class procedure TGeneratorUtilities.AddHMacKeyGenerator(const AAlgorithm: String
FKgAlgorithms.AddOrSetValue(LAlias, LMainName);
end;
-class procedure TGeneratorUtilities.Boot;
+class constructor TGeneratorUtilities.Create;
begin
FKgAlgorithms := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FKpgAlgorithms := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FDefaultKeySizes := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
- TNistObjectIdentifiers.Boot;
- TIanaObjectIdentifiers.Boot;
-
// key generators
AddKgAlgorithm('AES', ['AESWRAP']);
AddKgAlgorithm('AES128',
- [TNistObjectIdentifiers.IdAes128Cbc.ID,
- TNistObjectIdentifiers.IdAes128Cfb.ID,
- TNistObjectIdentifiers.IdAes128Ecb.ID,
- TNistObjectIdentifiers.IdAes128Ofb.ID,
- TNistObjectIdentifiers.IdAes128Wrap.ID,
- TNistObjectIdentifiers.IdAes128WrapPad.ID]);
+ [TNistObjectIdentifiers.IdAes128Cbc.ID,
+ TNistObjectIdentifiers.IdAes128Cfb.ID,
+ TNistObjectIdentifiers.IdAes128Ecb.ID,
+ TNistObjectIdentifiers.IdAes128Ofb.ID,
+ TNistObjectIdentifiers.IdAes128Wrap.ID,
+ TNistObjectIdentifiers.IdAes128WrapPad.ID]);
AddKgAlgorithm('AES192',
- [TNistObjectIdentifiers.IdAes192Cbc.ID,
- TNistObjectIdentifiers.IdAes192Cfb.ID,
- TNistObjectIdentifiers.IdAes192Ecb.ID,
- TNistObjectIdentifiers.IdAes192Ofb.ID,
- TNistObjectIdentifiers.IdAes192Wrap.ID,
- TNistObjectIdentifiers.IdAes192WrapPad.ID]);
+ [TNistObjectIdentifiers.IdAes192Cbc.ID,
+ TNistObjectIdentifiers.IdAes192Cfb.ID,
+ TNistObjectIdentifiers.IdAes192Ecb.ID,
+ TNistObjectIdentifiers.IdAes192Ofb.ID,
+ TNistObjectIdentifiers.IdAes192Wrap.ID,
+ TNistObjectIdentifiers.IdAes192WrapPad.ID]);
AddKgAlgorithm('AES256',
- [TNistObjectIdentifiers.IdAes256Cbc.ID,
- TNistObjectIdentifiers.IdAes256Cfb.ID,
- TNistObjectIdentifiers.IdAes256Ecb.ID,
- TNistObjectIdentifiers.IdAes256Ofb.ID,
- TNistObjectIdentifiers.IdAes256Wrap.ID,
- TNistObjectIdentifiers.IdAes256WrapPad.ID]);
+ [TNistObjectIdentifiers.IdAes256Cbc.ID,
+ TNistObjectIdentifiers.IdAes256Cfb.ID,
+ TNistObjectIdentifiers.IdAes256Ecb.ID,
+ TNistObjectIdentifiers.IdAes256Ofb.ID,
+ TNistObjectIdentifiers.IdAes256Wrap.ID,
+ TNistObjectIdentifiers.IdAes256WrapPad.ID]);
AddKgAlgorithm('BLOWFISH', ['1.3.6.1.4.1.3029.1.2']);
@@ -230,11 +226,9 @@ class procedure TGeneratorUtilities.Boot;
AddHMacKeyGenerator('MD4', []);
AddHMacKeyGenerator('MD5', [TIanaObjectIdentifiers.HmacMD5.ID]);
- TPkcsObjectIdentifiers.Boot;
-
AddHMacKeyGenerator('SHA1',
- [TPkcsObjectIdentifiers.IdHmacWithSha1.ID,
- TIanaObjectIdentifiers.HmacSha1.ID]);
+ [TPkcsObjectIdentifiers.IdHmacWithSha1.ID,
+ TIanaObjectIdentifiers.HmacSha1.ID]);
AddHMacKeyGenerator('SHA224', [TPkcsObjectIdentifiers.IdHmacWithSha224.ID]);
AddHMacKeyGenerator('SHA256', [TPkcsObjectIdentifiers.IdHmacWithSha256.ID]);
AddHMacKeyGenerator('SHA384', [TPkcsObjectIdentifiers.IdHmacWithSha384.ID]);
@@ -249,53 +243,46 @@ class procedure TGeneratorUtilities.Boot;
AddHMacKeyGenerator('KECCAK512', []);
AddHMacKeyGenerator('SHA3-224',
- [TNistObjectIdentifiers.IdHMacWithSha3_224.ID]);
+ [TNistObjectIdentifiers.IdHMacWithSha3_224.ID]);
AddHMacKeyGenerator('SHA3-256',
- [TNistObjectIdentifiers.IdHMacWithSha3_256.ID]);
+ [TNistObjectIdentifiers.IdHMacWithSha3_256.ID]);
AddHMacKeyGenerator('SHA3-384',
- [TNistObjectIdentifiers.IdHMacWithSha3_384.ID]);
+ [TNistObjectIdentifiers.IdHMacWithSha3_384.ID]);
AddHMacKeyGenerator('SHA3-512',
- [TNistObjectIdentifiers.IdHMacWithSha3_512.ID]);
+ [TNistObjectIdentifiers.IdHMacWithSha3_512.ID]);
AddHMacKeyGenerator('RIPEMD128', []);
AddHMacKeyGenerator('RIPEMD160', [TIanaObjectIdentifiers.HmacRipeMD160.ID]);
AddHMacKeyGenerator('TIGER', [TIanaObjectIdentifiers.HmacTiger.ID]);
- TRosstandartObjectIdentifiers.Boot;
-
AddHMacKeyGenerator('GOST3411-2012-256',
- [TRosstandartObjectIdentifiers.IdTc26HmacGost3411_12_256.ID]);
+ [TRosstandartObjectIdentifiers.IdTc26HmacGost3411_12_256.ID]);
AddHMacKeyGenerator('GOST3411-2012-512',
- [TRosstandartObjectIdentifiers.IdTc26HmacGost3411_12_512.ID]);
+ [TRosstandartObjectIdentifiers.IdTc26HmacGost3411_12_512.ID]);
//
// key pair generators.
//
- TX9ObjectIdentifiers.Boot;
- TSecObjectIdentifiers.Boot;
-
AddKpgAlgorithm('DH', ['DIFFIEHELLMAN']);
AddKpgAlgorithm('DSA', []);
AddKpgAlgorithm('RSA', [TPkcsObjectIdentifiers.RsaEncryption.ID]);
AddKpgAlgorithm('RSASSA-PSS', []);
AddKpgAlgorithm('EC', [
- TX9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassStdDHSha224KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassStdDHSha256KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassStdDHSha384KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassStdDHSha512KdfScheme.ID,
- TX9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassCofactorDHSha224KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassCofactorDHSha256KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassCofactorDHSha384KdfScheme.ID,
- TSecObjectIdentifiers.DhSinglePassCofactorDHSha512KdfScheme.ID
- ]);
+ TX9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassStdDHSha224KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassStdDHSha256KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassStdDHSha384KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassStdDHSha512KdfScheme.ID,
+ TX9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassCofactorDHSha224KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassCofactorDHSha256KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassCofactorDHSha384KdfScheme.ID,
+ TSecObjectIdentifiers.DhSinglePassCofactorDHSha512KdfScheme.ID
+ ]);
AddKpgAlgorithm('ECDH', ['ECIES']);
AddKpgAlgorithm('ECDHC', []);
AddKpgAlgorithm('ECDSA', []);
- TEdECObjectIdentifiers.Boot;
-
AddKpgAlgorithm('Ed25519', ['Ed25519ctx', 'Ed25519ph', TEdECObjectIdentifiers.IdEd25519.ID]);
AddKpgAlgorithm('Ed448', ['Ed448ph', TEdECObjectIdentifiers.IdEd448.ID]);
AddKpgAlgorithm('BIP340Schnorr', []);
@@ -304,41 +291,37 @@ class procedure TGeneratorUtilities.Boot;
AddKpgAlgorithm('X448', [TEdECObjectIdentifiers.IdX448.ID]);
AddDefaultKeySizeEntries(128, [
- 'AES128',
- 'BLOWFISH',
- 'CHACHA',
- 'HMACMD2',
- 'HMACMD4',
- 'HMACMD5',
- 'HMACRIPEMD128',
- 'SALSA20'
- ]);
+ 'AES128',
+ 'BLOWFISH',
+ 'CHACHA',
+ 'HMACMD2',
+ 'HMACMD4',
+ 'HMACMD5',
+ 'HMACRIPEMD128',
+ 'SALSA20'
+ ]);
AddDefaultKeySizeEntries(160, ['HMACRIPEMD160', 'HMACSHA1']);
AddDefaultKeySizeEntries(192, ['AES', 'AES192', 'HMACTIGER', 'RIJNDAEL']);
- AddDefaultKeySizeEntries(224,
- ['HMACSHA3-224',
- 'HMACKECCAK224',
- 'HMACSHA224',
- 'HMACSHA512/224']);
+ AddDefaultKeySizeEntries(224, [
+ 'HMACSHA3-224',
+ 'HMACKECCAK224',
+ 'HMACSHA224',
+ 'HMACSHA512/224'
+ ]);
AddDefaultKeySizeEntries(256, [
- 'AES256',
- 'HMACGOST3411-2012-256',
- 'HMACSHA3-256',
- 'HMACKECCAK256',
- 'HMACSHA256',
- 'HMACSHA512/256',
- 'XCHACHA20'
- ]);
+ 'AES256',
+ 'HMACGOST3411-2012-256',
+ 'HMACSHA3-256',
+ 'HMACKECCAK256',
+ 'HMACSHA256',
+ 'HMACSHA512/256',
+ 'XCHACHA20'
+ ]);
AddDefaultKeySizeEntries(288, ['HMACKECCAK288']);
AddDefaultKeySizeEntries(384, ['HMACSHA3-384', 'HMACKECCAK384', 'HMACSHA384']);
AddDefaultKeySizeEntries(512, ['HMACGOST3411-2012-512', 'HMACSHA3-512', 'HMACKECCAK512', 'HMACSHA512']);
end;
-class constructor TGeneratorUtilities.Create;
-begin
- Boot;
-end;
-
class destructor TGeneratorUtilities.Destroy;
begin
FKgAlgorithms.Free;
diff --git a/CryptoLib/src/Crypto/Generators/ClpHkdfBytesGenerator.pas b/CryptoLib/src/Crypto/Generators/ClpHkdfBytesGenerator.pas
index c00d0ced..0a43fe52 100644
--- a/CryptoLib/src/Crypto/Generators/ClpHkdfBytesGenerator.pas
+++ b/CryptoLib/src/Crypto/Generators/ClpHkdfBytesGenerator.pas
@@ -140,6 +140,9 @@ function THkdfBytesGenerator.Extract(const ASalt, AIkm: TCryptoLibByteArray): IK
var
LTemp, LPrk: TCryptoLibByteArray;
begin
+ // RFC 5869 sec. 2.2: when no salt is provided it defaults to HashLen zero octets,
+ // where HashLen is the hash output length. FHashLen is exactly that length
+ // (AHash.GetDigestSize() in Create), which for an HMac also equals its GetMacSize().
if ASalt = nil then
begin
System.SetLength(LTemp, FHashLen);
diff --git a/CryptoLib/src/Crypto/Generators/ClpX25519Generators.pas b/CryptoLib/src/Crypto/Generators/ClpX25519Generators.pas
index 96ff24f7..9325e37e 100644
--- a/CryptoLib/src/Crypto/Generators/ClpX25519Generators.pas
+++ b/CryptoLib/src/Crypto/Generators/ClpX25519Generators.pas
@@ -31,12 +31,18 @@ interface
ClpIAsymmetricCipherKeyPairGenerator;
type
+ ///
+ /// Key-pair generator for X25519 (RFC 7748). Only the from the supplied
+ /// key-generation parameters is used; the 32-byte clamped scalar is drawn directly from it.
+ ///
TX25519KeyPairGenerator = class sealed(TInterfacedObject,
IX25519KeyPairGenerator, IAsymmetricCipherKeyPairGenerator)
strict private
FRandom: ISecureRandom;
public
+ /// Capture the that will source the scalar.
procedure Init(const AParameters: IKeyGenerationParameters);
+ /// Generate a fresh X25519 key pair.
function GenerateKeyPair(): IAsymmetricCipherKeyPair;
end;
diff --git a/CryptoLib/src/Crypto/Generators/ClpX448Generators.pas b/CryptoLib/src/Crypto/Generators/ClpX448Generators.pas
index 486594bd..b5cafeb9 100644
--- a/CryptoLib/src/Crypto/Generators/ClpX448Generators.pas
+++ b/CryptoLib/src/Crypto/Generators/ClpX448Generators.pas
@@ -31,12 +31,18 @@ interface
ClpIAsymmetricCipherKeyPairGenerator;
type
+ ///
+ /// Key-pair generator for X448 (RFC 7748). Only the from the supplied
+ /// key-generation parameters is used; the 56-byte clamped scalar is drawn directly from it.
+ ///
TX448KeyPairGenerator = class sealed(TInterfacedObject,
IX448KeyPairGenerator, IAsymmetricCipherKeyPairGenerator)
strict private
FRandom: ISecureRandom;
public
+ /// Capture the that will source the scalar.
procedure Init(const AParameters: IKeyGenerationParameters);
+ /// Generate a fresh X448 key pair.
function GenerateKeyPair(): IAsymmetricCipherKeyPair;
end;
diff --git a/CryptoLib/src/Crypto/Macs/ClpMacUtilities.pas b/CryptoLib/src/Crypto/Macs/ClpMacUtilities.pas
index d47f692c..04ad8f02 100644
--- a/CryptoLib/src/Crypto/Macs/ClpMacUtilities.pas
+++ b/CryptoLib/src/Crypto/Macs/ClpMacUtilities.pas
@@ -69,7 +69,6 @@ TMacUtilities = class sealed(TObject)
class function GetMechanism(const AAlgorithm: String): String; static;
class function GetMacForMechanism(const AMechanism: String): IMac; static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
public
@@ -113,18 +112,11 @@ implementation
{ TMacUtilities }
-class procedure TMacUtilities.Boot;
+class constructor TMacUtilities.Create;
begin
FAlgorithmMap := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FAlgorithmOidMap := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
- TIanaObjectIdentifiers.Boot;
- TPkcsObjectIdentifiers.Boot;
- TMiscObjectIdentifiers.Boot;
- TNistObjectIdentifiers.Boot;
- TRosstandartObjectIdentifiers.Boot;
- TOiwObjectIdentifiers.Boot;
-
FAlgorithmOidMap.AddOrSetValue(TIanaObjectIdentifiers.HmacMD5, 'HMAC-MD5');
FAlgorithmOidMap.AddOrSetValue(TIanaObjectIdentifiers.HmacRipeMD160, 'HMAC-RIPEMD160');
FAlgorithmOidMap.AddOrSetValue(TIanaObjectIdentifiers.HmacSha1, 'HMAC-SHA1');
@@ -152,11 +144,6 @@ class procedure TMacUtilities.Boot;
FAlgorithmOidMap.AddOrSetValue(TOiwObjectIdentifiers.IdSha1, 'PBEWITHHMACSHA1');
end;
-class constructor TMacUtilities.Create;
-begin
- Boot;
-end;
-
class destructor TMacUtilities.Destroy;
begin
FAlgorithmMap.Free;
diff --git a/CryptoLib/src/Crypto/Modes/ClpBlockCipherBulkUtilities.pas b/CryptoLib/src/Crypto/Modes/ClpBlockCipherBulkUtilities.pas
index 4f91d6c4..d65bd92f 100644
--- a/CryptoLib/src/Crypto/Modes/ClpBlockCipherBulkUtilities.pas
+++ b/CryptoLib/src/Crypto/Modes/ClpBlockCipherBulkUtilities.pas
@@ -29,28 +29,10 @@ interface
type
///
- /// Shared scalar helpers for bulk block-cipher mode
- /// implementations: 16 / 64 / 128-byte triple-XOR primitives plus
- /// the IBulkBlockCipher / IBulkBlockCipherMode capability probes.
+ /// Shared helpers for bulk block-cipher mode implementations.
///
TBlockCipherBulkUtilities = class sealed(TObject)
public
- /// Scalar triple-XOR of 16 bytes:
- /// PDst^ := PSrcA^ xor PSrcB^.
- class procedure Xor16Bytes(PDst, PSrcA, PSrcB: PByte); static;
-
- ///
- /// Scalar triple-XOR of 64 bytes. Intentionally NOT inline: FPC
- /// 3.2 for i386 miscompiles the equivalent inline loop inside
- /// the pipelined GCM steps at -O3 (stale %edx reused as the loop
- /// index), so the CALL boundary is load-bearing.
- ///
- class procedure Xor64Bytes(PDst, PSrcA, PSrcB: PByte); static;
-
- /// 128-byte counterpart of Xor64Bytes. Same non-inline
- /// constraint applies.
- class procedure Xor128Bytes(PDst, PSrcA, PSrcB: PByte); static;
-
///
/// Probe ACipher for IBulkBlockCipher. ABulk is nil on False so
/// the caller can blindly assign into an existing field.
@@ -70,33 +52,6 @@ implementation
{ TBlockCipherBulkUtilities }
-class procedure TBlockCipherBulkUtilities.Xor16Bytes(PDst, PSrcA,
- PSrcB: PByte);
-begin
- PUInt64(PDst)^ := PUInt64(PSrcA)^ xor PUInt64(PSrcB)^;
- PUInt64(PDst + 8)^ := PUInt64(PSrcA + 8)^ xor PUInt64(PSrcB + 8)^;
-end;
-
-class procedure TBlockCipherBulkUtilities.Xor64Bytes(PDst, PSrcA,
- PSrcB: PByte);
-var
- LI: Int32;
-begin
- for LI := 0 to 7 do
- PUInt64(PDst + LI * 8)^ := PUInt64(PSrcA + LI * 8)^ xor
- PUInt64(PSrcB + LI * 8)^;
-end;
-
-class procedure TBlockCipherBulkUtilities.Xor128Bytes(PDst, PSrcA,
- PSrcB: PByte);
-var
- LI: Int32;
-begin
- for LI := 0 to 15 do
- PUInt64(PDst + LI * 8)^ := PUInt64(PSrcA + LI * 8)^ xor
- PUInt64(PSrcB + LI * 8)^;
-end;
-
class function TBlockCipherBulkUtilities.TryResolveBulkCipher(
const ACipher: IBlockCipher; out ABulk: IBulkBlockCipher): Boolean;
begin
diff --git a/CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas b/CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas
index 666c907a..3eb208ba 100644
--- a/CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas
+++ b/CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas
@@ -31,6 +31,7 @@ interface
ClpIParametersWithIV,
ClpArrayUtilities,
ClpBlockCipherBulkUtilities,
+ ClpByteUtilities,
ClpCryptoLibTypes;
resourcestring
@@ -304,18 +305,14 @@ function TCfbBlockCipher.ProcessBlocks(const AInBuf: TCryptoLibByteArray;
LK := 0;
while LK + 128 <= LTotalBytes do
begin
- TBlockCipherBulkUtilities.Xor128Bytes(
- PByte(@AOutBuf[AOutOff + LK]),
- PByte(@LScratch[LK]),
- PByte(@AInBuf[AInOff + LK]));
+ TByteUtilities.&Xor(128, PByte(LScratch) + LK, PByte(AInBuf) + AInOff + LK,
+ PByte(AOutBuf) + AOutOff + LK);
LK := LK + 128;
end;
while LK + 64 <= LTotalBytes do
begin
- TBlockCipherBulkUtilities.Xor64Bytes(
- PByte(@AOutBuf[AOutOff + LK]),
- PByte(@LScratch[LK]),
- PByte(@AInBuf[AInOff + LK]));
+ TByteUtilities.&Xor(64, PByte(LScratch) + LK, PByte(AInBuf) + AInOff + LK,
+ PByte(AOutBuf) + AOutOff + LK);
LK := LK + 64;
end;
for LI := LK to LTotalBytes - 1 do
diff --git a/CryptoLib/src/Crypto/Modes/ClpGcmBlockCipher.pas b/CryptoLib/src/Crypto/Modes/ClpGcmBlockCipher.pas
index 4d9291c0..1dd07155 100644
--- a/CryptoLib/src/Crypto/Modes/ClpGcmBlockCipher.pas
+++ b/CryptoLib/src/Crypto/Modes/ClpGcmBlockCipher.pas
@@ -38,6 +38,7 @@ interface
ClpTables4kGcmMultiplier,
ClpIBulkBlockCipher,
ClpBlockCipherBulkUtilities,
+ ClpByteUtilities,
ClpFusedKernelTypes,
ClpIFusedGcmKernel,
ClpFusedKernelRegistry,
@@ -1190,12 +1191,9 @@ procedure TGcmBlockCipher.GhashFourShuffledBlocks(PC0, PC16, PC32, PC48: PByte);
end;
{$ENDIF CRYPTOLIB_X86_SIMD}
GcmReverse16(@FS[0], @LSRev[0]);
- PUInt64(@LU0[0])^ := 0;
- PUInt64(@LU0[8])^ := 0;
- PUInt64(@LU1[0])^ := 0;
- PUInt64(@LU1[8])^ := 0;
- PUInt64(@LU2[0])^ := 0;
- PUInt64(@LU2[8])^ := 0;
+ FillChar(LU0, 16, 0);
+ FillChar(LU1, 16, 0);
+ FillChar(LU2, 16, 0);
for LB := 0 to 3 do
begin
case LB of
@@ -1241,22 +1239,14 @@ procedure TGcmBlockCipher.ProcessBlocks4Fused(const AInBuf: TCryptoLibByteArray;
AInOff: Int32; const AOutBuf: TCryptoLibByteArray; AOutOff: Int32;
AForEncrypt: Boolean);
var
- LI, LBase: Int32;
LPHash: PByte;
begin
GetNextCtrBlocks4(FWorkCtr);
- for LBase := 0 to 3 do
- begin
- LI := LBase * 16;
- PUInt64(@AOutBuf[AOutOff + LI])^ := PUInt64(@AInBuf[AInOff + LI])^ xor
- PUInt64(@FWorkCtr[LI])^;
- PUInt64(@AOutBuf[AOutOff + LI + 8])^ := PUInt64(@AInBuf[AInOff + LI + 8])^ xor
- PUInt64(@FWorkCtr[LI + 8])^;
- end;
+ TByteUtilities.&Xor(64, PByte(AInBuf) + AInOff, PByte(FWorkCtr), PByte(AOutBuf) + AOutOff);
if AForEncrypt then
- LPHash := @AOutBuf[AOutOff]
+ LPHash := PByte(AOutBuf) + AOutOff
else
- LPHash := @AInBuf[AInOff];
+ LPHash := PByte(AInBuf) + AInOff;
GhashFourShuffledBlocks(LPHash, LPHash + 16, LPHash + 32, LPHash + 48);
end;
@@ -1277,12 +1267,9 @@ procedure TGcmBlockCipher.GhashEightShuffledBlocks(PBase: PByte);
end;
{$ENDIF CRYPTOLIB_X86_SIMD}
GcmReverse16(@FS[0], @LSRev[0]);
- PUInt64(@LU0[0])^ := 0;
- PUInt64(@LU0[8])^ := 0;
- PUInt64(@LU1[0])^ := 0;
- PUInt64(@LU1[8])^ := 0;
- PUInt64(@LU2[0])^ := 0;
- PUInt64(@LU2[8])^ := 0;
+ FillChar(LU0, 16, 0);
+ FillChar(LU1, 16, 0);
+ FillChar(LU2, 16, 0);
for LB := 0 to 7 do
begin
LPCiph := PBase + (LB * 16);
@@ -1302,22 +1289,14 @@ procedure TGcmBlockCipher.ProcessBlocks8Fused(const AInBuf: TCryptoLibByteArray;
AInOff: Int32; const AOutBuf: TCryptoLibByteArray; AOutOff: Int32;
AForEncrypt: Boolean);
var
- LI, LBase: Int32;
LPHash: PByte;
begin
GetNextCtrBlocks8(FWorkCtr);
- for LBase := 0 to 7 do
- begin
- LI := LBase * 16;
- PUInt64(@AOutBuf[AOutOff + LI])^ := PUInt64(@AInBuf[AInOff + LI])^ xor
- PUInt64(@FWorkCtr[LI])^;
- PUInt64(@AOutBuf[AOutOff + LI + 8])^ := PUInt64(@AInBuf[AInOff + LI + 8])^ xor
- PUInt64(@FWorkCtr[LI + 8])^;
- end;
+ TByteUtilities.&Xor(128, PByte(AInBuf) + AInOff, PByte(FWorkCtr), PByte(AOutBuf) + AOutOff);
if AForEncrypt then
- LPHash := @AOutBuf[AOutOff]
+ LPHash := PByte(AOutBuf) + AOutOff
else
- LPHash := @AInBuf[AInOff];
+ LPHash := PByte(AInBuf) + AInOff;
GhashEightShuffledBlocks(LPHash);
end;
@@ -1347,21 +1326,21 @@ procedure TGcmBlockCipher.ProcessBlocks4Pipelined(const AInBuf: TCryptoLibByteAr
while ALen >= ALimit + (BlockSize * 4) * 2 do
begin
- LPIn := @AInBuf[AInOff];
- LPOut := @AOutBuf[AOutOff];
- LPKey := @LCurr[0];
+ LPIn := PByte(AInBuf) + AInOff;
+ LPOut := PByte(AOutBuf) + AOutOff;
+ LPKey := PByte(LCurr);
GetNextCtrBlocks4(LNext);
if AForEncrypt then
begin
- TBlockCipherBulkUtilities.Xor64Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(64, LPIn, LPKey, LPOut);
GhashFourShuffledBlocks(LPOut, LPOut + 16, LPOut + 32, LPOut + 48);
end
else
begin
GhashFourShuffledBlocks(LPIn, LPIn + 16, LPIn + 32, LPIn + 48);
- TBlockCipherBulkUtilities.Xor64Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(64, LPIn, LPKey, LPOut);
end;
LTmp := LCurr; LCurr := LNext; LNext := LTmp;
@@ -1370,18 +1349,18 @@ procedure TGcmBlockCipher.ProcessBlocks4Pipelined(const AInBuf: TCryptoLibByteAr
ALen := ALen - (BlockSize * 4);
end;
- LPIn := @AInBuf[AInOff];
- LPOut := @AOutBuf[AOutOff];
- LPKey := @LCurr[0];
+ LPIn := PByte(AInBuf) + AInOff;
+ LPOut := PByte(AOutBuf) + AOutOff;
+ LPKey := PByte(LCurr);
if AForEncrypt then
begin
- TBlockCipherBulkUtilities.Xor64Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(64, LPIn, LPKey, LPOut);
GhashFourShuffledBlocks(LPOut, LPOut + 16, LPOut + 32, LPOut + 48);
end
else
begin
GhashFourShuffledBlocks(LPIn, LPIn + 16, LPIn + 32, LPIn + 48);
- TBlockCipherBulkUtilities.Xor64Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(64, LPIn, LPKey, LPOut);
end;
AInOff := AInOff + (BlockSize * 4);
@@ -1409,21 +1388,21 @@ procedure TGcmBlockCipher.ProcessBlocks8Pipelined(const AInBuf: TCryptoLibByteAr
while ALen >= ALimit + (BlockSize * 8) * 2 do
begin
- LPIn := @AInBuf[AInOff];
- LPOut := @AOutBuf[AOutOff];
- LPKey := @LCurr[0];
+ LPIn := PByte(AInBuf) + AInOff;
+ LPOut := PByte(AOutBuf) + AOutOff;
+ LPKey := PByte(LCurr);
GetNextCtrBlocks8(LNext);
if AForEncrypt then
begin
- TBlockCipherBulkUtilities.Xor128Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(128, LPIn, LPKey, LPOut);
GhashEightShuffledBlocks(LPOut);
end
else
begin
GhashEightShuffledBlocks(LPIn);
- TBlockCipherBulkUtilities.Xor128Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(128, LPIn, LPKey, LPOut);
end;
LTmp := LCurr; LCurr := LNext; LNext := LTmp;
@@ -1432,18 +1411,18 @@ procedure TGcmBlockCipher.ProcessBlocks8Pipelined(const AInBuf: TCryptoLibByteAr
ALen := ALen - (BlockSize * 8);
end;
- LPIn := @AInBuf[AInOff];
- LPOut := @AOutBuf[AOutOff];
- LPKey := @LCurr[0];
+ LPIn := PByte(AInBuf) + AInOff;
+ LPOut := PByte(AOutBuf) + AOutOff;
+ LPKey := PByte(LCurr);
if AForEncrypt then
begin
- TBlockCipherBulkUtilities.Xor128Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(128, LPIn, LPKey, LPOut);
GhashEightShuffledBlocks(LPOut);
end
else
begin
GhashEightShuffledBlocks(LPIn);
- TBlockCipherBulkUtilities.Xor128Bytes(LPOut, LPIn, LPKey);
+ TByteUtilities.&Xor(128, LPIn, LPKey, LPOut);
end;
AInOff := AInOff + (BlockSize * 8);
@@ -1528,7 +1507,6 @@ procedure TGcmBlockCipher.ProcessBlocks8FusedILP(const AInBuf: TCryptoLibByteArr
var
LCurrCtrs, LNextCtrs: TCryptoLibByteArray;
LPrevCipher, LPOut, LPIn: PByte;
- LI: Int32;
begin
if FGcmKernel = nil then
Exit;
@@ -1541,10 +1519,9 @@ procedure TGcmBlockCipher.ProcessBlocks8FusedILP(const AInBuf: TCryptoLibByteArr
// Prime batch 0: regular 8-wide AES-NI into LCurrCtrs (now holds keystream),
// XOR with plaintext/ciphertext at LPOut, defer GHASH of batch 0.
GetNextCtrBlocks8(LCurrCtrs);
- LPIn := @AInBuf[AInOff];
- LPOut := @AOutBuf[AOutOff];
- for LI := 0 to 15 do
- PUInt64(LPOut + LI * 8)^ := PUInt64(LPIn + LI * 8)^ xor PUInt64(@LCurrCtrs[LI * 8])^;
+ LPIn := PByte(AInBuf) + AInOff;
+ LPOut := PByte(AOutBuf) + AOutOff;
+ TByteUtilities.&Xor(128, LPIn, PByte(LCurrCtrs), LPOut);
if AForEncrypt then
LPrevCipher := LPOut
@@ -1559,8 +1536,8 @@ procedure TGcmBlockCipher.ProcessBlocks8FusedILP(const AInBuf: TCryptoLibByteArr
// Fill raw (pre-AES) counter blocks; the kernel AES-encrypts them in-place.
FillNextCtrBlocks8Raw(LNextCtrs);
- LPIn := @AInBuf[AInOff];
- LPOut := @AOutBuf[AOutOff];
+ LPIn := PByte(AInBuf) + AInOff;
+ LPOut := PByte(AOutBuf) + AOutOff;
FGcmKernel.ProcessCtrGhashBatch(LPIn, LPOut, @LNextCtrs[0], LPrevCipher,
@FS[0], FGcmKernelMinBlocks);
@@ -1578,19 +1555,17 @@ procedure TGcmBlockCipher.ProcessBlocks8FusedILP(const AInBuf: TCryptoLibByteArr
GhashEightShuffledBlocks(LPrevCipher);
GetNextCtrBlocks8(LCurrCtrs);
- LPIn := @AInBuf[AInOff];
- LPOut := @AOutBuf[AOutOff];
+ LPIn := PByte(AInBuf) + AInOff;
+ LPOut := PByte(AOutBuf) + AOutOff;
if AForEncrypt then
begin
- for LI := 0 to 15 do
- PUInt64(LPOut + LI * 8)^ := PUInt64(LPIn + LI * 8)^ xor PUInt64(@LCurrCtrs[LI * 8])^;
+ TByteUtilities.&Xor(128, LPIn, PByte(LCurrCtrs), LPOut);
GhashEightShuffledBlocks(LPOut);
end
else
begin
GhashEightShuffledBlocks(LPIn);
- for LI := 0 to 15 do
- PUInt64(LPOut + LI * 8)^ := PUInt64(LPIn + LI * 8)^ xor PUInt64(@LCurrCtrs[LI * 8])^;
+ TByteUtilities.&Xor(128, LPIn, PByte(LCurrCtrs), LPOut);
end;
AInOff := AInOff + (BlockSize * 8);
diff --git a/CryptoLib/src/Crypto/Modes/ClpGcmSivBlockCipher.pas b/CryptoLib/src/Crypto/Modes/ClpGcmSivBlockCipher.pas
index 6220892c..76f6d6d2 100644
--- a/CryptoLib/src/Crypto/Modes/ClpGcmSivBlockCipher.pas
+++ b/CryptoLib/src/Crypto/Modes/ClpGcmSivBlockCipher.pas
@@ -650,10 +650,8 @@ function TGcmSivBlockCipher.EncryptPlain(const ACounter: TCryptoLibByteArray;
while LMyRemaining >= 128 do
begin
ProcessEightBlocksSivCtr(LMyCounter, LMyCounters);
- TBlockCipherBulkUtilities.Xor128Bytes(
- PByte(@ATarget[AOffset + LMyOff]),
- PByte(@LMyCounters[0]),
- PByte(@LMySrc[LMyOff]));
+ TByteUtilities.&Xor(128, PByte(LMyCounters), PByte(LMySrc) + LMyOff,
+ PByte(ATarget) + AOffset + LMyOff);
LMyRemaining := LMyRemaining - 128;
LMyOff := LMyOff + 128;
end;
@@ -715,10 +713,8 @@ procedure TGcmSivBlockCipher.DecryptPlain;
while LMyRemaining >= 128 do
begin
ProcessEightBlocksSivCtr(LMyCounter, LMyCounters);
- TBlockCipherBulkUtilities.Xor128Bytes(
- PByte(@LMyScratch128[0]),
- PByte(@LMyCounters[0]),
- PByte(@LMySrc[LMyOff]));
+ TByteUtilities.&Xor(128, PByte(LMyCounters), PByte(LMySrc) + LMyOff,
+ PByte(LMyScratch128));
FThePlain.Write(LMyScratch128[0], 128);
FTheDataHasher.UpdateHash(LMyScratch128, 0, 128);
LMyRemaining := LMyRemaining - 128;
diff --git a/CryptoLib/src/Crypto/Modes/ClpOcbBlockCipher.pas b/CryptoLib/src/Crypto/Modes/ClpOcbBlockCipher.pas
index 3730e19b..8422ffef 100644
--- a/CryptoLib/src/Crypto/Modes/ClpOcbBlockCipher.pas
+++ b/CryptoLib/src/Crypto/Modes/ClpOcbBlockCipher.pas
@@ -677,13 +677,12 @@ procedure TOcbBlockCipher.ProcessEightBlocksBulk(
// Evolve the per-block offset ladder the exact same way ProcessMainBlock
// would: FOffsetMAIN_{k+1} = FOffsetMAIN_k XOR L[ntz(count+1)]. Materialise
// all 8 offsets consecutively in LOffsets[0..127] so the downstream XORs
- // run as a single 128-byte sweep via Xor128Bytes.
+ // run as a single 128-byte sweep via TByteUtilities.Xor.
for LI := 0 to 7 do
begin
System.Inc(FMainBlockCount);
LLSub := GetLSub(OCB_ntz(FMainBlockCount));
- TBlockCipherBulkUtilities.Xor16Bytes(@FOffsetMAIN[0], @FOffsetMAIN[0],
- @LLSub[0]);
+ TByteUtilities.&Xor(16, PByte(FOffsetMAIN), PByte(LLSub), PByte(FOffsetMAIN));
System.Move(FOffsetMAIN[0], LOffsets[LI * BLOCK_SIZE], BLOCK_SIZE);
end;
@@ -696,15 +695,13 @@ procedure TOcbBlockCipher.ProcessEightBlocksBulk(
FChecksum, 0);
// LScratch := AInput XOR LOffsets (one 128-byte XOR)
- TBlockCipherBulkUtilities.Xor128Bytes(@LScratch[0], @AInput[AInOff],
- @LOffsets[0]);
+ TByteUtilities.&Xor(128, PByte(AInput) + AInOff, PByte(@LOffsets[0]), PByte(@LScratch[0]));
// In-place bulk encrypt (aliasing-safe per IBulkBlockCipher contract).
FMainBulk.ProcessBlocks(@LScratch[0], @LScratch[0], 8);
// AOutput := LScratch XOR LOffsets (one 128-byte XOR)
- TBlockCipherBulkUtilities.Xor128Bytes(@AOutput[AOutOff], @LScratch[0],
- @LOffsets[0]);
+ TByteUtilities.&Xor(128, PByte(@LScratch[0]), PByte(@LOffsets[0]), PByte(AOutput) + AOutOff);
end
else
begin
@@ -716,13 +713,11 @@ procedure TOcbBlockCipher.ProcessEightBlocksBulk(
System.Move(FMainBlock[0], LScratch[0], FMacSize);
System.Move(AInput[AInOff], LScratch[FMacSize], 128 - FMacSize);
- TBlockCipherBulkUtilities.Xor128Bytes(@LScratch[0], @LScratch[0],
- @LOffsets[0]);
+ TByteUtilities.&Xor(128, PByte(@LScratch[0]), PByte(@LOffsets[0]), PByte(@LScratch[0]));
FMainBulk.ProcessBlocks(@LScratch[0], @LScratch[0], 8);
- TBlockCipherBulkUtilities.Xor128Bytes(@LScratch[0], @LScratch[0],
- @LOffsets[0]);
+ TByteUtilities.&Xor(128, PByte(@LScratch[0]), PByte(@LOffsets[0]), PByte(@LScratch[0]));
System.Move(LScratch[0], AOutput[AOutOff], 128);
@@ -768,18 +763,15 @@ function TOcbBlockCipher.DoFinal(const AOutput: TCryptoLibByteArray;
if FForEncryption then
begin
OCB_extend(FMainBlock, FMainBlockPos);
- TBlockCipherBulkUtilities.Xor16Bytes(@FChecksum[0], @FChecksum[0],
- @FMainBlock[0]);
+ TByteUtilities.&Xor(16, PByte(FChecksum), PByte(FMainBlock), PByte(FChecksum));
end;
- TBlockCipherBulkUtilities.Xor16Bytes(@FOffsetMAIN[0], @FOffsetMAIN[0],
- @FL_Asterisk[0]);
+ TByteUtilities.&Xor(16, PByte(FOffsetMAIN), PByte(FL_Asterisk), PByte(FOffsetMAIN));
System.SetLength(LPad, 16);
FHashCipher.ProcessBlock(FOffsetMAIN, 0, LPad, 0);
- TBlockCipherBulkUtilities.Xor16Bytes(@FMainBlock[0], @FMainBlock[0],
- @LPad[0]);
+ TByteUtilities.&Xor(16, PByte(FMainBlock), PByte(LPad), PByte(FMainBlock));
TCheck.OutputLength(AOutput, AOutOff, FMainBlockPos, SOutputBufferTooShort);
System.Move(FMainBlock[0], AOutput[AOutOff], FMainBlockPos);
@@ -787,18 +779,14 @@ function TOcbBlockCipher.DoFinal(const AOutput: TCryptoLibByteArray;
if (not FForEncryption) then
begin
OCB_extend(FMainBlock, FMainBlockPos);
- TBlockCipherBulkUtilities.Xor16Bytes(@FChecksum[0], @FChecksum[0],
- @FMainBlock[0]);
+ TByteUtilities.&Xor(16, PByte(FChecksum), PByte(FMainBlock), PByte(FChecksum));
end;
end;
- TBlockCipherBulkUtilities.Xor16Bytes(@FChecksum[0], @FChecksum[0],
- @FOffsetMAIN[0]);
- TBlockCipherBulkUtilities.Xor16Bytes(@FChecksum[0], @FChecksum[0],
- @FL_Dollar[0]);
+ TByteUtilities.&Xor(16, PByte(FChecksum), PByte(FOffsetMAIN), PByte(FChecksum));
+ TByteUtilities.&Xor(16, PByte(FChecksum), PByte(FL_Dollar), PByte(FChecksum));
FHashCipher.ProcessBlock(FChecksum, 0, FChecksum, 0);
- TBlockCipherBulkUtilities.Xor16Bytes(@FChecksum[0], @FChecksum[0],
- @FSum[0]);
+ TByteUtilities.&Xor(16, PByte(FChecksum), PByte(FSum), PByte(FChecksum));
System.SetLength(FMacBlock, FMacSize);
System.Move(FChecksum[0], FMacBlock[0], FMacSize);
@@ -861,28 +849,23 @@ procedure TOcbBlockCipher.ProcessMainBlock(const AOutput: TCryptoLibByteArray;
if FForEncryption then
begin
- TBlockCipherBulkUtilities.Xor16Bytes(@FChecksum[0], @FChecksum[0],
- @FMainBlock[0]);
+ TByteUtilities.&Xor(16, PByte(FChecksum), PByte(FMainBlock), PByte(FChecksum));
FMainBlockPos := 0;
end;
System.Inc(FMainBlockCount);
LLSub := GetLSub(OCB_ntz(FMainBlockCount));
- TBlockCipherBulkUtilities.Xor16Bytes(@FOffsetMAIN[0], @FOffsetMAIN[0],
- @LLSub[0]);
+ TByteUtilities.&Xor(16, PByte(FOffsetMAIN), PByte(LLSub), PByte(FOffsetMAIN));
- TBlockCipherBulkUtilities.Xor16Bytes(@FMainBlock[0], @FMainBlock[0],
- @FOffsetMAIN[0]);
+ TByteUtilities.&Xor(16, PByte(FMainBlock), PByte(FOffsetMAIN), PByte(FMainBlock));
FMainCipher.ProcessBlock(FMainBlock, 0, FMainBlock, 0);
- TBlockCipherBulkUtilities.Xor16Bytes(@FMainBlock[0], @FMainBlock[0],
- @FOffsetMAIN[0]);
+ TByteUtilities.&Xor(16, PByte(FMainBlock), PByte(FOffsetMAIN), PByte(FMainBlock));
System.Move(FMainBlock[0], AOutput[AOutOff], 16);
if (not FForEncryption) then
begin
- TBlockCipherBulkUtilities.Xor16Bytes(@FChecksum[0], @FChecksum[0],
- @FMainBlock[0]);
+ TByteUtilities.&Xor(16, PByte(FChecksum), PByte(FMainBlock), PByte(FChecksum));
System.Move(FMainBlock[BLOCK_SIZE], FMainBlock[0], FMacSize);
FMainBlockPos := FMacSize;
end;
@@ -918,12 +901,10 @@ procedure TOcbBlockCipher.Reset(AClearMac: Boolean);
procedure TOcbBlockCipher.UpdateHASH(const ALSub: TCryptoLibByteArray);
begin
- TBlockCipherBulkUtilities.Xor16Bytes(@FOffsetHASH[0], @FOffsetHASH[0],
- @ALSub[0]);
- TBlockCipherBulkUtilities.Xor16Bytes(@FHashBlock[0], @FHashBlock[0],
- @FOffsetHASH[0]);
+ TByteUtilities.&Xor(16, PByte(FOffsetHASH), PByte(ALSub), PByte(FOffsetHASH));
+ TByteUtilities.&Xor(16, PByte(FHashBlock), PByte(FOffsetHASH), PByte(FHashBlock));
FHashCipher.ProcessBlock(FHashBlock, 0, FHashBlock, 0);
- TBlockCipherBulkUtilities.Xor16Bytes(@FSum[0], @FSum[0], @FHashBlock[0]);
+ TByteUtilities.&Xor(16, PByte(FSum), PByte(FHashBlock), PByte(FSum));
end;
class function TOcbBlockCipher.OCB_double(
diff --git a/CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas b/CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas
index 76748168..c99261d7 100644
--- a/CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas
+++ b/CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas
@@ -28,6 +28,7 @@ interface
ClpIBulkBlockCipher,
ClpIBulkBlockCipherMode,
ClpBlockCipherBulkUtilities,
+ ClpByteUtilities,
ClpISicBlockCipher,
ClpICipherParameters,
ClpIParametersWithIV,
@@ -318,8 +319,7 @@ procedure TSicBlockCipher.ProcessEightBlocksBulk(
// IBulkBlockCipher aliasing contract) turns LKs from raw counter
// blocks into keystream.
FBulkCipher.ProcessBlocks(@LKs[0], @LKs[0], 8);
- TBlockCipherBulkUtilities.Xor128Bytes(@AOutBuf[AOutOff], @AInBuf[AInOff],
- @LKs[0]);
+ TByteUtilities.&Xor(128, PByte(AInBuf) + AInOff, @LKs[0], PByte(AOutBuf) + AOutOff);
end;
end.
diff --git a/CryptoLib/src/Crypto/Modes/Gcm/ClpGcmUtilities.pas b/CryptoLib/src/Crypto/Modes/Gcm/ClpGcmUtilities.pas
index c380a00e..2269715a 100644
--- a/CryptoLib/src/Crypto/Modes/Gcm/ClpGcmUtilities.pas
+++ b/CryptoLib/src/Crypto/Modes/Gcm/ClpGcmUtilities.pas
@@ -27,7 +27,8 @@ interface
ClpInterleave,
ClpCpuFeatures,
ClpCryptoLibTypes,
- ClpIntrinsicsVector;
+ ClpIntrinsicsVector,
+ ClpByteUtilities;
type
TFieldElement = record
@@ -65,10 +66,10 @@ TGcmUtilities = class sealed(TObject)
class procedure Reduce3(PZ0, PZ1, PZ2, PSVector16: PByte); static;
/// Xor three 16-byte limbs with three 16-byte slices from a 48-byte MultiplyExt output.
class procedure XorMultiplyExtLimbs48(PA0, PA1, PA2, PSrc48: PByte); static;
+{$IFDEF CRYPTOLIB_X86_SIMD}
/// HPow[0..7] = H^8..H^1 as 16-byte limbs at offsets 0,16,...,112 (index 0 = H^8). Four-way fused GHASH uses offsets 64..112 (H^4..H^1).
class procedure InitEightWayHPowFromH(const AH: TCryptoLibByteArray; const AHPow128: TCryptoLibByteArray); static;
-{$IFDEF CRYPTOLIB_X86_SIMD}
/// Fused GHASH for four 16-byte ciphertext blocks. PFS 16-byte in/out (canonical); PC0 points to 64 contiguous ciphertext bytes; PHPow64 = H^4..H^1 (64 bytes); PMask = 16-byte SSSE3 PSHUFB control.
class procedure FusedFourShuffledGhash(PFS, PC0, PHPow64, PMask: PByte); static;
/// Fused GHASH for eight 16-byte ciphertext blocks. PHPow128 = H^8..H^1 (128 bytes at FHPow[0]).
@@ -431,9 +432,9 @@ class procedure TGcmUtilities.XorMultiplyExtLimbs48(PA0, PA1, PA2, PSrc48: PByte
{$ENDIF CRYPTOLIB_X86_SIMD}
for LK := 0 to 1 do
begin
- PUInt64(PA0 + LK * 8)^ := PUInt64(PA0 + LK * 8)^ xor PUInt64(PSrc48 + LK * 8)^;
- PUInt64(PA1 + LK * 8)^ := PUInt64(PA1 + LK * 8)^ xor PUInt64(PSrc48 + 16 + LK * 8)^;
- PUInt64(PA2 + LK * 8)^ := PUInt64(PA2 + LK * 8)^ xor PUInt64(PSrc48 + 32 + LK * 8)^;
+ TByteUtilities.XorTo(8, PSrc48 + LK * 8, PA0 + LK * 8);
+ TByteUtilities.XorTo(8, PSrc48 + 16 + LK * 8, PA1 + LK * 8);
+ TByteUtilities.XorTo(8, PSrc48 + 32 + LK * 8, PA2 + LK * 8);
end;
end;
@@ -502,8 +503,6 @@ class procedure TGcmUtilities.FusedEightShuffledGhash(PFS, PC0, PHPow128, PMask:
GcmGhashEightFull(PFS, PC0, PHPow128, PMask);
end;
-{$ENDIF CRYPTOLIB_X86_SIMD}
-
class procedure TGcmUtilities.InitEightWayHPowFromH(const AH: TCryptoLibByteArray;
const AHPow128: TCryptoLibByteArray);
var
@@ -554,4 +553,6 @@ class procedure TGcmUtilities.InitEightWayHPowFromH(const AH: TCryptoLibByteArra
PUInt64(@AHPow128[120])^ := LF1.N0;
end;
+{$ENDIF CRYPTOLIB_X86_SIMD}
+
end.
diff --git a/CryptoLib/src/Crypto/Operators/ClpDefaultDigestAlgorithmFinder.pas b/CryptoLib/src/Crypto/Operators/ClpDefaultDigestAlgorithmFinder.pas
index 196d2e13..40ef4a30 100644
--- a/CryptoLib/src/Crypto/Operators/ClpDefaultDigestAlgorithmFinder.pas
+++ b/CryptoLib/src/Crypto/Operators/ClpDefaultDigestAlgorithmFinder.pas
@@ -57,7 +57,6 @@ TDefaultDigestAlgorithmFinder = class sealed(TInterfacedObject, IDigestAlgorit
FDigestOids: TDictionary;
FDigestNameToOids: TDictionary;
FDigestOidToAlgIDs: TDictionary;
- class procedure Boot; static;
class procedure AddDigestAlgID(const AOid: IDerObjectIdentifier;
AWithNullParams: Boolean); static;
class constructor Create;
@@ -83,19 +82,6 @@ class procedure TDefaultDigestAlgorithmFinder.AddDigestAlgID(
end;
class constructor TDefaultDigestAlgorithmFinder.Create;
-begin
- Boot;
-end;
-
-class destructor TDefaultDigestAlgorithmFinder.Destroy;
-begin
- FInstance := nil;
- FDigestOids.Free;
- FDigestNameToOids.Free;
- FDigestOidToAlgIDs.Free;
-end;
-
-class procedure TDefaultDigestAlgorithmFinder.Boot;
begin
FDigestOids := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
FDigestNameToOids := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
@@ -261,6 +247,14 @@ class procedure TDefaultDigestAlgorithmFinder.Boot;
FInstance := TDefaultDigestAlgorithmFinder.Create;
end;
+class destructor TDefaultDigestAlgorithmFinder.Destroy;
+begin
+ FInstance := nil;
+ FDigestOids.Free;
+ FDigestNameToOids.Free;
+ FDigestOidToAlgIDs.Free;
+end;
+
function TDefaultDigestAlgorithmFinder.Find(const ASignatureAlgorithm: IAlgorithmIdentifier): IAlgorithmIdentifier;
var
LSignatureOid, LDigestOid: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Crypto/Operators/ClpDefaultMacAlgorithmFinder.pas b/CryptoLib/src/Crypto/Operators/ClpDefaultMacAlgorithmFinder.pas
index 2a896da4..41be166a 100644
--- a/CryptoLib/src/Crypto/Operators/ClpDefaultMacAlgorithmFinder.pas
+++ b/CryptoLib/src/Crypto/Operators/ClpDefaultMacAlgorithmFinder.pas
@@ -42,7 +42,6 @@ TDefaultMacAlgorithmFinder = class sealed(TInterfacedObject, IMacAlgorithmFind
class var
FInstance: IMacAlgorithmFinder;
FMacNameToAlgIDs: TDictionary;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
public
@@ -55,53 +54,48 @@ implementation
{ TDefaultMacAlgorithmFinder }
class constructor TDefaultMacAlgorithmFinder.Create;
-begin
- Boot;
-end;
-
-class destructor TDefaultMacAlgorithmFinder.Destroy;
-begin
- FInstance := nil;
- FMacNameToAlgIDs.Free;
-end;
-
-class procedure TDefaultMacAlgorithmFinder.Boot;
begin
FMacNameToAlgIDs := TDictionary.Create(
- TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
+ TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FMacNameToAlgIDs.Add('HMACSHA1',
- TAlgorithmIdentifier.Create(TOiwObjectIdentifiers.IdSha1) as IAlgorithmIdentifier);
+ TAlgorithmIdentifier.Create(TOiwObjectIdentifiers.IdSha1) as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA224',
- TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha224, TDerNull.Instance)
+ TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha224, TDerNull.Instance)
as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA256',
- TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha256, TDerNull.Instance)
+ TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha256, TDerNull.Instance)
as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA384',
- TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha384, TDerNull.Instance)
+ TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha384, TDerNull.Instance)
as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA512',
- TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha512, TDerNull.Instance)
+ TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha512, TDerNull.Instance)
as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA512-224',
- TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha512_224, TDerNull.Instance)
+ TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha512_224, TDerNull.Instance)
as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA512-256',
- TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha512_256, TDerNull.Instance)
+ TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdHmacWithSha512_256, TDerNull.Instance)
as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA3-224',
- TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_224) as IAlgorithmIdentifier);
+ TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_224) as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA3-256',
- TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_256) as IAlgorithmIdentifier);
+ TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_256) as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA3-384',
- TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_384) as IAlgorithmIdentifier);
+ TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_384) as IAlgorithmIdentifier);
FMacNameToAlgIDs.Add('HMACSHA3-512',
- TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_512) as IAlgorithmIdentifier);
+ TAlgorithmIdentifier.Create(TNistObjectIdentifiers.IdHMacWithSha3_512) as IAlgorithmIdentifier);
FInstance := TDefaultMacAlgorithmFinder.Create;
end;
+class destructor TDefaultMacAlgorithmFinder.Destroy;
+begin
+ FInstance := nil;
+ FMacNameToAlgIDs.Free;
+end;
+
function TDefaultMacAlgorithmFinder.Find(const AMacName: String): IAlgorithmIdentifier;
begin
Result := TCollectionUtilities.GetValueOrNull(
diff --git a/CryptoLib/src/Crypto/Operators/ClpDefaultSignatureAlgorithmFinder.pas b/CryptoLib/src/Crypto/Operators/ClpDefaultSignatureAlgorithmFinder.pas
index cdd6ff80..5fa9bf47 100644
--- a/CryptoLib/src/Crypto/Operators/ClpDefaultSignatureAlgorithmFinder.pas
+++ b/CryptoLib/src/Crypto/Operators/ClpDefaultSignatureAlgorithmFinder.pas
@@ -73,7 +73,6 @@ TDefaultSignatureAlgorithmFinder = class sealed(TInterfacedObject, ISignatureA
const AParameters: IAsn1Encodable); static;
class function CreatePssParams(const ADigAlgID: IAlgorithmIdentifier;
ASaltSize: Int32): IRsassaPssParameters; static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
public
@@ -86,104 +85,20 @@ implementation
{ TDefaultSignatureAlgorithmFinder }
class constructor TDefaultSignatureAlgorithmFinder.Create;
-begin
- Boot;
-end;
-
-class destructor TDefaultSignatureAlgorithmFinder.Destroy;
-begin
- FInstance := nil;
- FAlgorithms.Free;
- FNoParams.Free;
- FParameters.Free;
- FPkcs15RsaEncryption.Free;
- FDigestOids.Free;
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.AddAlgorithm(const AName: String;
- const AOid: IDerObjectIdentifier);
-begin
- FAlgorithms.Add(AName, AOid);
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.AddAlgorithm(const AName: String;
- const AOid: IDerObjectIdentifier; AIsNoParams: Boolean);
-begin
- AddAlgorithm(AName, AOid, nil, AIsNoParams);
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.AddAlgorithm(const AName: String;
- const AOid: IDerObjectIdentifier; const ADigestOid: IDerObjectIdentifier; AIsNoParams: Boolean);
-begin
- if AName = '' then
- raise EArgumentNilCryptoLibException.Create('name');
- if AOid = nil then
- raise EArgumentNilCryptoLibException.Create('oid');
-
- AddAlgorithm(AName, AOid);
-
- if ADigestOid <> nil then
- AddDigestOid(AOid, ADigestOid);
- if AIsNoParams then
- AddNoParams(AOid);
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.AddDigestOid(const ASignatureOid,
- ADigestOid: IDerObjectIdentifier);
-begin
- FDigestOids.Add(ASignatureOid, ADigestOid);
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.AddPkcs15RsaEncryption(
- const AOid: IDerObjectIdentifier);
-begin
- if not FPkcs15RsaEncryption.ContainsKey(AOid) then
- FPkcs15RsaEncryption.Add(AOid, 0);
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.AddNoParams(const AOid: IDerObjectIdentifier);
-begin
- if not FNoParams.ContainsKey(AOid) then
- FNoParams.Add(AOid, TAlgorithmIdentifier.Create(AOid) as IAlgorithmIdentifier);
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.AddParameters(const AAlgorithmName: String;
- const AParameters: IAsn1Encodable);
-begin
- if AParameters = nil then
- raise EArgumentCryptoLibException.Create('use ''NoParams'' instead for absent parameters');
- FParameters.Add(AAlgorithmName, AParameters);
-end;
-
-class function TDefaultSignatureAlgorithmFinder.CreatePssParams(
- const ADigAlgID: IAlgorithmIdentifier; ASaltSize: Int32): IRsassaPssParameters;
-var
- LHashAlgId: IAlgorithmIdentifier;
- LMgfAlgId: IAlgorithmIdentifier;
- LSaltLength: IDerInteger;
-begin
- LHashAlgId := ADigAlgID;
- LMgfAlgId := TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdMgf1, LHashAlgId);
- LSaltLength := TDerInteger.Create(ASaltSize);
- Result := TRsassaPssParameters.Create(LHashAlgId, LMgfAlgId, LSaltLength,
- TRsassaPssParameters.DefaultTrailerField);
-end;
-
-class procedure TDefaultSignatureAlgorithmFinder.Boot;
var
LSha1AlgId, LSha224AlgId, LSha256AlgId, LSha384AlgId, LSha512AlgId: IAlgorithmIdentifier;
LSha3_224AlgId, LSha3_256AlgId, LSha3_384AlgId, LSha3_512AlgId: IAlgorithmIdentifier;
begin
FAlgorithms := TDictionary.Create(
- TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
+ TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FNoParams := TDictionary.Create(
- TAsn1Comparers.OidEqualityComparer);
+ TAsn1Comparers.OidEqualityComparer);
FParameters := TDictionary.Create(
- TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
+ TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FPkcs15RsaEncryption := TDictionary.Create(
- TAsn1Comparers.OidEqualityComparer);
+ TAsn1Comparers.OidEqualityComparer);
FDigestOids := TDictionary.Create(
- TAsn1Comparers.OidEqualityComparer);
+ TAsn1Comparers.OidEqualityComparer);
AddAlgorithm('MD2WITHRSAENCRYPTION', TPkcsObjectIdentifiers.MD2WithRsaEncryption);
AddAlgorithm('MD2WITHRSA', TPkcsObjectIdentifiers.MD2WithRsaEncryption);
@@ -273,25 +188,25 @@ class procedure TDefaultSignatureAlgorithmFinder.Boot;
AddAlgorithm('GOST3411WITHECGOST3410-2001', TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
AddAlgorithm('GOST3411WITHGOST3410-2001', TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
AddAlgorithm('GOST3411WITHECGOST3410-2012-256',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
AddAlgorithm('GOST3411WITHECGOST3410-2012-512',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
AddAlgorithm('GOST3411WITHGOST3410-2012-256',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
AddAlgorithm('GOST3411WITHGOST3410-2012-512',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
AddAlgorithm('GOST3411-2012-256WITHECGOST3410-2012-256',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
AddAlgorithm('GOST3411-2012-512WITHECGOST3410-2012-512',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
AddAlgorithm('GOST3411-2012-256WITHGOST3410-2012-256',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
AddAlgorithm('GOST3411-2012-512WITHGOST3410-2012-512',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
AddAlgorithm('GOST3411-2012-256WITHECGOST3410',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256);
AddAlgorithm('GOST3411-2012-512WITHECGOST3410',
- TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
+ TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512);
AddAlgorithm('SHA1WITHCVC-ECDSA', TEacObjectIdentifiers.IdTAEcdsaSha1);
AddAlgorithm('SHA224WITHCVC-ECDSA', TEacObjectIdentifiers.IdTAEcdsaSha224);
@@ -437,19 +352,19 @@ class procedure TDefaultSignatureAlgorithmFinder.Boot;
AddDigestOid(TPkcsObjectIdentifiers.MD5WithRsaEncryption, TPkcsObjectIdentifiers.MD5);
AddDigestOid(TPkcsObjectIdentifiers.Sha1WithRsaEncryption, TOiwObjectIdentifiers.IdSha1);
AddDigestOid(TTeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128,
- TTeleTrusTObjectIdentifiers.RipeMD128);
+ TTeleTrusTObjectIdentifiers.RipeMD128);
AddDigestOid(TTeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160,
- TTeleTrusTObjectIdentifiers.RipeMD160);
+ TTeleTrusTObjectIdentifiers.RipeMD160);
AddDigestOid(TTeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256,
- TTeleTrusTObjectIdentifiers.RipeMD256);
+ TTeleTrusTObjectIdentifiers.RipeMD256);
AddDigestOid(TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94,
- TCryptoProObjectIdentifiers.GostR3411);
+ TCryptoProObjectIdentifiers.GostR3411);
AddDigestOid(TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001,
- TCryptoProObjectIdentifiers.GostR3411);
+ TCryptoProObjectIdentifiers.GostR3411);
AddDigestOid(TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_256,
- TRosstandartObjectIdentifiers.IdTc26Gost3411_12_256);
+ TRosstandartObjectIdentifiers.IdTc26Gost3411_12_256);
AddDigestOid(TRosstandartObjectIdentifiers.IdTc26SignWithDigestGost3410_12_512,
- TRosstandartObjectIdentifiers.IdTc26Gost3411_12_512);
+ TRosstandartObjectIdentifiers.IdTc26Gost3411_12_512);
AddDigestOid(TX9ObjectIdentifiers.IdDsaWithSha1, TOiwObjectIdentifiers.IdSha1);
AddDigestOid(TOiwObjectIdentifiers.DsaWithSha1, TOiwObjectIdentifiers.IdSha1);
@@ -488,6 +403,85 @@ class procedure TDefaultSignatureAlgorithmFinder.Boot;
FInstance := TDefaultSignatureAlgorithmFinder.Create;
end;
+class destructor TDefaultSignatureAlgorithmFinder.Destroy;
+begin
+ FInstance := nil;
+ FAlgorithms.Free;
+ FNoParams.Free;
+ FParameters.Free;
+ FPkcs15RsaEncryption.Free;
+ FDigestOids.Free;
+end;
+
+class procedure TDefaultSignatureAlgorithmFinder.AddAlgorithm(const AName: String;
+ const AOid: IDerObjectIdentifier);
+begin
+ FAlgorithms.Add(AName, AOid);
+end;
+
+class procedure TDefaultSignatureAlgorithmFinder.AddAlgorithm(const AName: String;
+ const AOid: IDerObjectIdentifier; AIsNoParams: Boolean);
+begin
+ AddAlgorithm(AName, AOid, nil, AIsNoParams);
+end;
+
+class procedure TDefaultSignatureAlgorithmFinder.AddAlgorithm(const AName: String;
+ const AOid: IDerObjectIdentifier; const ADigestOid: IDerObjectIdentifier; AIsNoParams: Boolean);
+begin
+ if AName = '' then
+ raise EArgumentNilCryptoLibException.Create('name');
+ if AOid = nil then
+ raise EArgumentNilCryptoLibException.Create('oid');
+
+ AddAlgorithm(AName, AOid);
+
+ if ADigestOid <> nil then
+ AddDigestOid(AOid, ADigestOid);
+ if AIsNoParams then
+ AddNoParams(AOid);
+end;
+
+class procedure TDefaultSignatureAlgorithmFinder.AddDigestOid(const ASignatureOid,
+ ADigestOid: IDerObjectIdentifier);
+begin
+ FDigestOids.Add(ASignatureOid, ADigestOid);
+end;
+
+class procedure TDefaultSignatureAlgorithmFinder.AddPkcs15RsaEncryption(
+ const AOid: IDerObjectIdentifier);
+begin
+ if not FPkcs15RsaEncryption.ContainsKey(AOid) then
+ FPkcs15RsaEncryption.Add(AOid, 0);
+end;
+
+class procedure TDefaultSignatureAlgorithmFinder.AddNoParams(const AOid: IDerObjectIdentifier);
+begin
+ if not FNoParams.ContainsKey(AOid) then
+ FNoParams.Add(AOid, TAlgorithmIdentifier.Create(AOid) as IAlgorithmIdentifier);
+end;
+
+class procedure TDefaultSignatureAlgorithmFinder.AddParameters(const AAlgorithmName: String;
+ const AParameters: IAsn1Encodable);
+begin
+ if AParameters = nil then
+ raise EArgumentCryptoLibException.Create('use ''NoParams'' instead for absent parameters');
+ FParameters.Add(AAlgorithmName, AParameters);
+end;
+
+class function TDefaultSignatureAlgorithmFinder.CreatePssParams(
+ const ADigAlgID: IAlgorithmIdentifier; ASaltSize: Int32): IRsassaPssParameters;
+var
+ LHashAlgId: IAlgorithmIdentifier;
+ LMgfAlgId: IAlgorithmIdentifier;
+ LSaltLength: IDerInteger;
+begin
+ LHashAlgId := ADigAlgID;
+ LMgfAlgId := TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdMgf1, LHashAlgId);
+ LSaltLength := TDerInteger.ValueOf(ASaltSize);
+ Result := TRsassaPssParameters.Create(LHashAlgId, LMgfAlgId, LSaltLength,
+ TRsassaPssParameters.DefaultTrailerField);
+end;
+
function TDefaultSignatureAlgorithmFinder.Find(const ASignatureName: String): IAlgorithmIdentifier;
var
LSigOid: IDerObjectIdentifier;
diff --git a/CryptoLib/src/Crypto/Parameters/ClpEd25519Parameters.pas b/CryptoLib/src/Crypto/Parameters/ClpEd25519Parameters.pas
index 7979584d..9e3d4e02 100644
--- a/CryptoLib/src/Crypto/Parameters/ClpEd25519Parameters.pas
+++ b/CryptoLib/src/Crypto/Parameters/ClpEd25519Parameters.pas
@@ -43,6 +43,11 @@ interface
SMsgLen = 'MsgLen must be Equal to PreHashSize for Ed25519ph Algorithm';
type
+ ///
+ /// Ed25519 public key (RFC 8032). Wraps a decoded curve point obtained from a 32-byte encoded
+ /// representation; the point is validated at construction so that subsequent verifications work
+ /// against a known-good key.
+ ///
TEd25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
IEd25519PublicKeyParameters)
@@ -51,17 +56,60 @@ TEd25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
FPublicPoint: TEd25519.IPublicPoint;
public
+ /// Length in bytes of an Ed25519 public key encoding (32).
const
KeySize = Int32(TEd25519.PublicKeySize);
+ ///
+ /// Construct from a 32-byte buffer holding the encoded public point.
+ ///
+ ///
+ /// If length differs from , or the encoding does
+ /// not decode to a valid curve point.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from starting at ; reads
+ /// bytes.
+ ///
+ ///
+ /// If the encoded bytes do not decode to a valid curve point.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read encoded bytes from and decode them.
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
+ ///
+ /// If the encoded bytes do not decode to a valid curve point.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Construct from an already-decoded curve point. No further validation is performed.
+ ///
+ /// If is nil.
+ ///
constructor Create(const APublicPoint: TEd25519.IPublicPoint); overload;
+ ///
+ /// Write the 32-byte encoded public point into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 32-byte encoded public point.
function GetEncoded(): TCryptoLibByteArray; inline;
+ ///
+ /// Verify an Ed25519 signature. Selects between pure Ed25519, Ed25519ctx and Ed25519ph based on
+ /// . The pure variant rejects a non-nil context; the context and
+ /// prehash variants require a context up to 255 bytes long, and Ed25519ph additionally requires
+ /// to equal .
+ ///
+ /// true if the signature is valid for this key; otherwise false.
+ ///
+ /// If exceeds 255 bytes, is supplied for pure Ed25519,
+ /// is wrong for Ed25519ph, or is
+ /// unrecognised.
+ ///
function Verify(AAlgorithm: TEd25519.TAlgorithm;
const ACtx, AMsg: TCryptoLibByteArray; AMsgOff, AMsgLen: Int32;
const ASig: TCryptoLibByteArray; ASigOff: Int32): Boolean;
@@ -72,6 +120,10 @@ TEd25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// Ed25519 private key (RFC 8032). Holds the 32-byte secret seed; the corresponding public key is
+ /// derived lazily on first use and cached.
+ ///
TEd25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
IEd25519PrivateKeyParameters)
@@ -81,19 +133,51 @@ TEd25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
FCachedPublicKey: IEd25519PublicKeyParameters;
public
+ /// Length in bytes of an Ed25519 private-key seed (32).
const
KeySize = Int32(TEd25519.SecretKeySize);
+ /// Length in bytes of an Ed25519 signature (64).
SignatureSize = Int32(TEd25519.SignatureSize);
+ /// Generate a fresh random Ed25519 private key using .
+ ///
constructor Create(const ARandom: ISecureRandom); overload;
+ /// Construct from a 32-byte seed buffer.
+ ///
+ /// If length differs from .
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from at ; reads
+ /// bytes.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read the 32-byte seed from .
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Write the 32-byte seed into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 32-byte seed.
function GetEncoded(): TCryptoLibByteArray; inline;
+ /// Derive (and cache) the public key corresponding to this private key.
function GeneratePublicKey(): IEd25519PublicKeyParameters;
+ ///
+ /// Compute an Ed25519 signature. Selects between pure Ed25519, Ed25519ctx and Ed25519ph based on
+ /// . The pure variant rejects a non-nil context; the context and
+ /// prehash variants require a context up to 255 bytes long, and Ed25519ph additionally requires
+ /// to equal .
+ ///
+ ///
+ /// If exceeds 255 bytes, is supplied for pure Ed25519,
+ /// is wrong for Ed25519ph, or is
+ /// unrecognised.
+ ///
procedure Sign(AAlgorithm: TEd25519.TAlgorithm;
const ACtx, AMsg: TCryptoLibByteArray; AMsgOff, AMsgLen: Int32;
const ASig: TCryptoLibByteArray; ASigOff: Int32);
@@ -104,10 +188,17 @@ TEd25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// Key generation parameters for Ed25519 (RFC 8032). Carries the used for
+ /// seed generation; the strength is fixed at 256 bits.
+ ///
TEd25519KeyGenerationParameters = class sealed(TKeyGenerationParameters,
IEd25519KeyGenerationParameters)
public
+ ///
+ /// Construct using as the entropy source for the 32-byte seed.
+ ///
constructor Create(const ARandom: ISecureRandom);
end;
diff --git a/CryptoLib/src/Crypto/Parameters/ClpEd448Parameters.pas b/CryptoLib/src/Crypto/Parameters/ClpEd448Parameters.pas
index 3adbda70..575cec11 100644
--- a/CryptoLib/src/Crypto/Parameters/ClpEd448Parameters.pas
+++ b/CryptoLib/src/Crypto/Parameters/ClpEd448Parameters.pas
@@ -42,6 +42,10 @@ interface
SMsgLen = 'MsgLen must be Equal to PreHashSize for Ed448ph Algorithm';
type
+ ///
+ /// Ed448 public key (RFC 8032). Wraps a decoded curve point obtained from a 57-byte encoded
+ /// representation; the point is validated at construction.
+ ///
TEd448PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
IEd448PublicKeyParameters)
@@ -50,17 +54,56 @@ TEd448PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
FPublicPoint: TEd448.IPublicPoint;
public
+ /// Length in bytes of an Ed448 public key encoding (57).
const
KeySize = Int32(57);
+ /// Construct from a 57-byte buffer holding the encoded public point.
+ ///
+ /// If length differs from , or the encoding does
+ /// not decode to a valid curve point.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from at ; reads
+ /// bytes.
+ ///
+ ///
+ /// If the encoded bytes do not decode to a valid curve point.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read encoded bytes from and decode them.
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
+ ///
+ /// If the encoded bytes do not decode to a valid curve point.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Construct from an already-decoded curve point. No further validation is performed.
+ ///
+ /// If is nil.
+ ///
constructor Create(const APublicPoint: TEd448.IPublicPoint); overload;
+ ///
+ /// Write the 57-byte encoded public point into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 57-byte encoded public point.
function GetEncoded(): TCryptoLibByteArray; inline;
+ ///
+ /// Verify an Ed448 signature. Both Ed448 and Ed448ph require a context up to 255 bytes;
+ /// Ed448ph additionally requires to equal
+ /// .
+ ///
+ /// true if the signature is valid for this key; otherwise false.
+ ///
+ /// If exceeds 255 bytes, is wrong for Ed448ph,
+ /// or is unrecognised.
+ ///
function Verify(AAlgorithm: TEd448.TAlgorithm;
const ACtx, AMsg: TCryptoLibByteArray; AMsgOff, AMsgLen: Int32;
const ASig: TCryptoLibByteArray; ASigOff: Int32): Boolean;
@@ -71,6 +114,10 @@ TEd448PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// Ed448 private key (RFC 8032). Holds the 57-byte secret seed; the corresponding public key is
+ /// derived lazily on first use and cached.
+ ///
TEd448PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
IEd448PrivateKeyParameters)
@@ -80,19 +127,49 @@ TEd448PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
FCachedPublicKey: IEd448PublicKeyParameters;
public
+ /// Length in bytes of an Ed448 private-key seed (57).
const
KeySize = Int32(57);
+ /// Length in bytes of an Ed448 signature (114).
SignatureSize = Int32(57 + 57);
+ /// Generate a fresh random Ed448 private key using .
+ ///
constructor Create(const ARandom: ISecureRandom); overload;
+ /// Construct from a 57-byte seed buffer.
+ ///
+ /// If length differs from .
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from at ; reads
+ /// bytes.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read the 57-byte seed from .
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Write the 57-byte seed into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 57-byte seed.
function GetEncoded(): TCryptoLibByteArray; inline;
+ /// Derive (and cache) the public key corresponding to this private key.
function GeneratePublicKey(): IEd448PublicKeyParameters;
+ ///
+ /// Compute an Ed448 signature. Both Ed448 and Ed448ph require a context up to 255 bytes;
+ /// Ed448ph additionally requires to equal
+ /// .
+ ///
+ ///
+ /// If exceeds 255 bytes, is wrong for Ed448ph,
+ /// or is unrecognised.
+ ///
procedure Sign(AAlgorithm: TEd448.TAlgorithm;
const ACtx, AMsg: TCryptoLibByteArray; AMsgOff, AMsgLen: Int32;
const ASig: TCryptoLibByteArray; ASigOff: Int32);
@@ -103,10 +180,17 @@ TEd448PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// Key generation parameters for Ed448 (RFC 8032). Carries the used for
+ /// seed generation; the strength is fixed at 448 bits.
+ ///
TEd448KeyGenerationParameters = class sealed(TKeyGenerationParameters,
IEd448KeyGenerationParameters)
public
+ ///
+ /// Construct using as the entropy source for the 57-byte seed.
+ ///
constructor Create(const ARandom: ISecureRandom);
end;
diff --git a/CryptoLib/src/Crypto/Parameters/ClpParameterUtilities.pas b/CryptoLib/src/Crypto/Parameters/ClpParameterUtilities.pas
index c6f29703..bbd01ac6 100644
--- a/CryptoLib/src/Crypto/Parameters/ClpParameterUtilities.pas
+++ b/CryptoLib/src/Crypto/Parameters/ClpParameterUtilities.pas
@@ -72,7 +72,6 @@ TParameterUtilities = class sealed(TObject)
class function CreateIV(const ARandom: ISecureRandom; AIVLength: Int32): TCryptoLibByteArray; static;
class function CreateIVOctetString(const ARandom: ISecureRandom;
AIVLength: Int32): IAsn1Encodable; static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
public
@@ -204,42 +203,39 @@ class function TParameterUtilities.CreateIVOctetString(const ARandom: ISecureRan
Result := TDerOctetString.Create(CreateIV(ARandom, AIVLength));
end;
-class procedure TParameterUtilities.Boot;
+class constructor TParameterUtilities.Create;
begin
- TNistObjectIdentifiers.Boot;
-
FAlgorithms := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FBasicIVSizes := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
AddAlgorithm('AES', ['AESWRAP']);
AddAlgorithm('AES128', [
- TNistObjectIdentifiers.IdAes128Cbc.ID,
- TNistObjectIdentifiers.IdAes128Cfb.ID,
- TNistObjectIdentifiers.IdAes128Ecb.ID,
- TNistObjectIdentifiers.IdAes128Ofb.ID,
- TNistObjectIdentifiers.IdAes128Wrap.ID,
- TNistObjectIdentifiers.IdAes128WrapPad.ID
- ]);
+ TNistObjectIdentifiers.IdAes128Cbc.ID,
+ TNistObjectIdentifiers.IdAes128Cfb.ID,
+ TNistObjectIdentifiers.IdAes128Ecb.ID,
+ TNistObjectIdentifiers.IdAes128Ofb.ID,
+ TNistObjectIdentifiers.IdAes128Wrap.ID,
+ TNistObjectIdentifiers.IdAes128WrapPad.ID
+ ]);
AddAlgorithm('AES192', [
- TNistObjectIdentifiers.IdAes192Cbc.ID,
- TNistObjectIdentifiers.IdAes192Cfb.ID,
- TNistObjectIdentifiers.IdAes192Ecb.ID,
- TNistObjectIdentifiers.IdAes192Ofb.ID,
- TNistObjectIdentifiers.IdAes192Wrap.ID,
- TNistObjectIdentifiers.IdAes192WrapPad.ID
- ]);
+ TNistObjectIdentifiers.IdAes192Cbc.ID,
+ TNistObjectIdentifiers.IdAes192Cfb.ID,
+ TNistObjectIdentifiers.IdAes192Ecb.ID,
+ TNistObjectIdentifiers.IdAes192Ofb.ID,
+ TNistObjectIdentifiers.IdAes192Wrap.ID,
+ TNistObjectIdentifiers.IdAes192WrapPad.ID
+ ]);
AddAlgorithm('AES256', [
- TNistObjectIdentifiers.IdAes256Cbc.ID,
- TNistObjectIdentifiers.IdAes256Cfb.ID,
- TNistObjectIdentifiers.IdAes256Ecb.ID,
- TNistObjectIdentifiers.IdAes256Ofb.ID,
- TNistObjectIdentifiers.IdAes256Wrap.ID,
- TNistObjectIdentifiers.IdAes256WrapPad.ID
- ]);
-
+ TNistObjectIdentifiers.IdAes256Cbc.ID,
+ TNistObjectIdentifiers.IdAes256Cfb.ID,
+ TNistObjectIdentifiers.IdAes256Ecb.ID,
+ TNistObjectIdentifiers.IdAes256Ofb.ID,
+ TNistObjectIdentifiers.IdAes256Wrap.ID,
+ TNistObjectIdentifiers.IdAes256WrapPad.ID
+ ]);
AddAlgorithm('BLOWFISH', ['1.3.6.1.4.1.3029.1.2', TMiscObjectIdentifiers.CryptlibAlgorithmBlowfishCbc.ID]);
@@ -257,11 +253,6 @@ class procedure TParameterUtilities.Boot;
AddBasicIVSizeEntries(24, ['XCHACHA20']);
end;
-class constructor TParameterUtilities.Create;
-begin
- Boot;
-end;
-
class destructor TParameterUtilities.Destroy;
begin
FAlgorithms.Free;
diff --git a/CryptoLib/src/Crypto/Parameters/ClpX25519Parameters.pas b/CryptoLib/src/Crypto/Parameters/ClpX25519Parameters.pas
index 339797d6..4e9e72e7 100644
--- a/CryptoLib/src/Crypto/Parameters/ClpX25519Parameters.pas
+++ b/CryptoLib/src/Crypto/Parameters/ClpX25519Parameters.pas
@@ -38,6 +38,11 @@ interface
SAgreementCalculationFailed = 'X25519 Agreement Failed';
type
+ ///
+ /// X25519 public key (RFC 7748). Holds the 32-byte u-coordinate of the peer's curve point. The
+ /// encoding is stored verbatim; validation of the point is performed during scalar multiplication
+ /// in the agreement primitive.
+ ///
TX25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
IX25519PublicKeyParameters)
@@ -48,14 +53,31 @@ TX25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
class function Validate(const ABuf: TCryptoLibByteArray): TCryptoLibByteArray; static;
public
+ /// Length in bytes of an X25519 public key encoding (32).
const
KeySize = Int32(TX25519.PointSize);
+ /// Construct from a 32-byte buffer holding the encoded u-coordinate.
+ ///
+ /// If length differs from .
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from at ; reads
+ /// bytes.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read the 32-byte encoded u-coordinate from .
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Write the 32-byte encoded u-coordinate into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 32-byte encoded u-coordinate.
function GetEncoded(): TCryptoLibByteArray; inline;
function Equals(const AOther: IX25519PublicKeyParameters): Boolean;
@@ -64,6 +86,10 @@ TX25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// X25519 private key (RFC 7748). Holds the 32-byte clamped scalar used in Curve25519
+ /// Diffie-Hellman.
+ ///
TX25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
IX25519PrivateKeyParameters)
@@ -74,18 +100,47 @@ TX25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
class function Validate(const ABuf: TCryptoLibByteArray): TCryptoLibByteArray; static;
public
+ /// Length in bytes of an X25519 private-key scalar (32).
const
KeySize = Int32(TX25519.ScalarSize);
+ /// Length in bytes of the shared secret produced by an X25519 agreement (32).
SecretSize = Int32(TX25519.PointSize);
+ /// Generate a fresh random X25519 private key using .
+ ///
constructor Create(const ARandom: ISecureRandom); overload;
+ /// Construct from a 32-byte scalar buffer.
+ ///
+ /// If length differs from .
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from at ; reads
+ /// bytes.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read the 32-byte scalar from .
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Write the 32-byte scalar into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 32-byte scalar.
function GetEncoded(): TCryptoLibByteArray; inline;
+ /// Compute the public key (u-coordinate) corresponding to this scalar.
function GeneratePublicKey(): IX25519PublicKeyParameters; inline;
+ ///
+ /// Perform an X25519 Diffie-Hellman agreement against and write the
+ /// resulting -byte shared secret into starting at
+ /// .
+ ///
+ ///
+ /// If the agreement produces an all-zero secret (degenerate peer key).
+ ///
procedure GenerateSecret(const APublicKey: IX25519PublicKeyParameters;
const ABuf: TCryptoLibByteArray; AOff: Int32);
@@ -95,10 +150,17 @@ TX25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// Key generation parameters for X25519 (RFC 7748). Carries the used for
+ /// scalar generation; the strength is fixed at 255 bits.
+ ///
TX25519KeyGenerationParameters = class sealed(TKeyGenerationParameters,
IX25519KeyGenerationParameters)
public
+ ///
+ /// Construct using as the entropy source for the 32-byte scalar.
+ ///
constructor Create(const ARandom: ISecureRandom);
end;
diff --git a/CryptoLib/src/Crypto/Parameters/ClpX448Parameters.pas b/CryptoLib/src/Crypto/Parameters/ClpX448Parameters.pas
index a9372588..eca19c76 100644
--- a/CryptoLib/src/Crypto/Parameters/ClpX448Parameters.pas
+++ b/CryptoLib/src/Crypto/Parameters/ClpX448Parameters.pas
@@ -38,6 +38,11 @@ interface
SAgreementCalculationFailed = 'X448 Agreement Failed';
type
+ ///
+ /// X448 public key (RFC 7748). Holds the 56-byte u-coordinate of the peer's curve point. The
+ /// encoding is stored verbatim; validation of the point is performed during scalar multiplication
+ /// in the agreement primitive.
+ ///
TX448PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
IX448PublicKeyParameters)
@@ -48,14 +53,31 @@ TX448PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
class function Validate(const ABuf: TCryptoLibByteArray): TCryptoLibByteArray; static;
public
+ /// Length in bytes of an X448 public key encoding (56).
const
KeySize = Int32(TX448.PointSize);
+ /// Construct from a 56-byte buffer holding the encoded u-coordinate.
+ ///
+ /// If length differs from .
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from at ; reads
+ /// bytes.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read the 56-byte encoded u-coordinate from .
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Write the 56-byte encoded u-coordinate into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 56-byte encoded u-coordinate.
function GetEncoded(): TCryptoLibByteArray; inline;
function Equals(const AOther: IX448PublicKeyParameters): Boolean;
@@ -64,6 +86,10 @@ TX448PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// X448 private key (RFC 7748). Holds the 56-byte clamped scalar used in Curve448
+ /// Diffie-Hellman.
+ ///
TX448PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
IX448PrivateKeyParameters)
@@ -74,18 +100,47 @@ TX448PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
class function Validate(const ABuf: TCryptoLibByteArray): TCryptoLibByteArray; static;
public
+ /// Length in bytes of an X448 private-key scalar (56).
const
KeySize = Int32(TX448.ScalarSize);
+ /// Length in bytes of the shared secret produced by an X448 agreement (56).
SecretSize = Int32(TX448.PointSize);
+ /// Generate a fresh random X448 private key using .
+ ///
constructor Create(const ARandom: ISecureRandom); overload;
+ /// Construct from a 56-byte scalar buffer.
+ ///
+ /// If length differs from .
+ ///
constructor Create(const ABuf: TCryptoLibByteArray); overload;
+ ///
+ /// Construct from at ; reads
+ /// bytes.
+ ///
constructor Create(const ABuf: TCryptoLibByteArray; AOff: Int32); overload;
+ /// Read the 56-byte scalar from .
+ ///
+ /// If the stream ends before bytes have been read.
+ ///
constructor Create(AInput: TStream); overload;
+ ///
+ /// Write the 56-byte scalar into at .
+ ///
procedure Encode(const ABuf: TCryptoLibByteArray; AOff: Int32); inline;
+ /// Return a fresh copy of the 56-byte scalar.
function GetEncoded(): TCryptoLibByteArray; inline;
+ /// Compute the public key (u-coordinate) corresponding to this scalar.
function GeneratePublicKey(): IX448PublicKeyParameters; inline;
+ ///
+ /// Perform an X448 Diffie-Hellman agreement against and write the
+ /// resulting -byte shared secret into starting at
+ /// .
+ ///
+ ///
+ /// If the agreement produces an all-zero secret (degenerate peer key).
+ ///
procedure GenerateSecret(const APublicKey: IX448PublicKeyParameters;
const ABuf: TCryptoLibByteArray; AOff: Int32);
@@ -95,10 +150,17 @@ TX448PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
{$ENDIF DELPHI}override;
end;
+ ///
+ /// Key generation parameters for X448 (RFC 7748). Carries the used for
+ /// scalar generation; the strength is fixed at 448 bits.
+ ///
TX448KeyGenerationParameters = class sealed(TKeyGenerationParameters,
IX448KeyGenerationParameters)
public
+ ///
+ /// Construct using as the entropy source for the 56-byte scalar.
+ ///
constructor Create(const ARandom: ISecureRandom);
end;
diff --git a/CryptoLib/src/Crypto/Randoms/ClpSecureRandom.pas b/CryptoLib/src/Crypto/Randoms/ClpSecureRandom.pas
index ffd8b89c..17f14477 100644
--- a/CryptoLib/src/Crypto/Randoms/ClpSecureRandom.pas
+++ b/CryptoLib/src/Crypto/Randoms/ClpSecureRandom.pas
@@ -54,7 +54,6 @@ TSecureRandom = class(TRandom, ISecureRandom)
FMasterRandom: ISecureRandom;
FDoubleScale: Double;
FLock: TCriticalSection;
- FIsBooted: Boolean;
class function GetMasterRandom: ISecureRandom; static; inline;
@@ -112,9 +111,6 @@ TSecureRandom = class(TRandom, ISecureRandom)
/// e.g. "SHA256PRNG"
/// If true, the instance will be auto-seeded.
class function GetInstance(const AAlgorithm: String; AAutoSeed: Boolean): ISecureRandom; overload; static;
-
- class procedure Boot(); static;
-
class property MasterRandom: ISecureRandom read GetMasterRandom;
end;
@@ -262,7 +258,12 @@ function TSecureRandom.NextInt64: Int64;
class constructor TSecureRandom.Create;
begin
- TSecureRandom.Boot;
+ FLock := TCriticalSection.Create;
+ FCounter := TDateTimeUtilities.DateTimeToTicks(Now.ToUniversalTime());
+ FMasterRandom := TSecureRandom.Create(TCryptoApiRandomGenerator.Create()
+ as ICryptoApiRandomGenerator);
+ FDoubleScale := Power(2.0, 64.0);
+ TOSRandomProvider.Instance;
end;
class destructor TSecureRandom.Destroy;
@@ -304,20 +305,6 @@ class function TSecureRandom.CreatePrng(const ADigestName: String;
Result := LPrng;
end;
-class procedure TSecureRandom.Boot;
-begin
- if not FIsBooted then
- begin
- FLock := TCriticalSection.Create;
- FCounter := TDateTimeUtilities.DateTimeToTicks(Now.ToUniversalTime());
- FMasterRandom := TSecureRandom.Create(TCryptoApiRandomGenerator.Create()
- as ICryptoApiRandomGenerator);
- FDoubleScale := Power(2.0, 64.0);
- TOSRandomProvider.Boot;
- FIsBooted := True;
- end;
-end;
-
constructor TSecureRandom.Create;
begin
Create(CreatePrng('SHA256', True));
diff --git a/CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas b/CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas
index 4f7c0c85..724c7807 100644
--- a/CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas
+++ b/CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas
@@ -55,8 +55,6 @@ TECDsaSigner = class(TInterfacedObject, IDsa, IECDsaSigner)
class var
FEight: TBigInteger;
-
- class procedure Boot(); static;
class constructor ECDsaSigner();
class function GetEight: TBigInteger; static; inline;
@@ -136,11 +134,6 @@ constructor TECDsaSigner.Create;
FKCalculator := TRandomDsaKCalculator.Create();
end;
-class procedure TECDsaSigner.Boot;
-begin
- FEight := TBigInteger.ValueOf(8);
-end;
-
function TECDsaSigner.CalculateE(const AN: TBigInteger;
const AMessage: TCryptoLibByteArray): TBigInteger;
var
@@ -171,7 +164,7 @@ function TECDsaSigner.CreateBasePointMultiplier: IECMultiplier;
class constructor TECDsaSigner.ECDsaSigner;
begin
- TECDsaSigner.Boot;
+ FEight := TBigInteger.ValueOf(8);
end;
function TECDsaSigner.GenerateSignature(const AMessage: TCryptoLibByteArray)
diff --git a/CryptoLib/src/Crypto/Signers/ClpEd25519CtxSigner.pas b/CryptoLib/src/Crypto/Signers/ClpEd25519CtxSigner.pas
index c1769c3e..75bb8023 100644
--- a/CryptoLib/src/Crypto/Signers/ClpEd25519CtxSigner.pas
+++ b/CryptoLib/src/Crypto/Signers/ClpEd25519CtxSigner.pas
@@ -39,6 +39,10 @@ interface
'Ed25519CtxSigner not Initialised for Verification';
type
+ ///
+ /// Ed25519ctx (RFC 8032 section 5.1) signature primitive: pure Ed25519 with a domain-separation context
+ /// of up to 255 bytes captured at construction.
+ ///
TEd25519CtxSigner = class(TInterfacedObject, ISigner, IEd25519CtxSigner)
strict private
@@ -80,18 +84,44 @@ TBuffer = class
function GetAlgorithmName: String; virtual;
public
+ ///
+ /// Construct an Ed25519ctx signer bound to the supplied . The context
+ /// bytes are cloned so the caller may mutate the array afterwards; nil is treated as empty.
+ ///
constructor Create(const AContext: TCryptoLibByteArray);
destructor Destroy(); override;
+ /// Initialise for signing (private key) or verification (public key).
+ ///
+ /// If is not an
+ /// (signing) or
+ /// (verification).
+ ///
procedure Init(AForSigning: Boolean;
const AParameters: ICipherParameters); virtual;
procedure Update(AInput: Byte); virtual;
procedure BlockUpdate(const ABuf: TCryptoLibByteArray;
AOff, ALength: Int32); virtual;
+ /// Length in bytes of an Ed25519ctx signature (64).
function GetMaxSignatureSize: Int32; virtual;
+ /// Finalise the buffered message and produce the signature. Buffer is reset on return.
+ ///
+ ///
+ /// If the signer was initialised for verification, not signing.
+ ///
function GenerateSignature(): TCryptoLibByteArray; virtual;
+ ///
+ /// Finalise the buffered message and verify . Buffer is reset on
+ /// return.
+ ///
+ /// true if the signature is valid for the accumulated message, bound public key and
+ /// captured context; otherwise false.
+ ///
+ /// If the signer was initialised for signing, not verification.
+ ///
function VerifySignature(const ASignature: TCryptoLibByteArray)
: Boolean; virtual;
+ /// Clear and rewind the buffered message; the captured context survives.
procedure Reset(); virtual;
property AlgorithmName: String read GetAlgorithmName;
diff --git a/CryptoLib/src/Crypto/Signers/ClpEd25519PhSigner.pas b/CryptoLib/src/Crypto/Signers/ClpEd25519PhSigner.pas
index ef5d076d..10e3a829 100644
--- a/CryptoLib/src/Crypto/Signers/ClpEd25519PhSigner.pas
+++ b/CryptoLib/src/Crypto/Signers/ClpEd25519PhSigner.pas
@@ -38,6 +38,10 @@ interface
SPreHashDigestFailed = 'PreHash Digest Failed';
type
+ ///
+ /// Ed25519ph (RFC 8032 section 5.1) signature primitive: pre-hashes the message with SHA-512 before
+ /// running pure Ed25519, parameterised by a fixed context captured at construction.
+ ///
TEd25519PhSigner = class(TInterfacedObject, ISigner, IEd25519PhSigner)
strict private
@@ -52,18 +56,42 @@ TEd25519PhSigner = class(TInterfacedObject, ISigner, IEd25519PhSigner)
function GetAlgorithmName: String; virtual;
public
+ ///
+ /// Construct an Ed25519ph signer bound to the supplied . The context
+ /// bytes are cloned so the caller may mutate the array afterwards; nil is treated as empty.
+ ///
constructor Create(const AContext: TCryptoLibByteArray);
destructor Destroy(); override;
+ /// Initialise for signing (private key) or verification (public key).
+ ///
+ /// If is not an
+ /// (signing) or
+ /// (verification).
+ ///
procedure Init(AForSigning: Boolean;
const AParameters: ICipherParameters); virtual;
procedure Update(AInput: Byte); virtual;
procedure BlockUpdate(const ABuf: TCryptoLibByteArray;
AOff, ALength: Int32); virtual;
+ /// Length in bytes of an Ed25519ph signature (64).
function GetMaxSignatureSize: Int32; virtual;
+ /// Finalise the pre-hash and produce the signature.
+ ///
+ /// If the signer was initialised for verification, not signing, or the pre-hash finalisation
+ /// produces an unexpected length.
+ ///
function GenerateSignature(): TCryptoLibByteArray; virtual;
+ /// Finalise the pre-hash and verify .
+ /// true if the signature is valid for the accumulated message, bound public key and
+ /// captured context; otherwise false.
+ ///
+ /// If the signer was initialised for signing, not verification, or the pre-hash finalisation
+ /// produces an unexpected length.
+ ///
function VerifySignature(const ASignature: TCryptoLibByteArray)
: Boolean; virtual;
+ /// Reset the pre-hash digest; the captured context survives.
procedure Reset(); virtual;
property AlgorithmName: String read GetAlgorithmName;
diff --git a/CryptoLib/src/Crypto/Signers/ClpEd25519Signer.pas b/CryptoLib/src/Crypto/Signers/ClpEd25519Signer.pas
index 85475caa..9485d738 100644
--- a/CryptoLib/src/Crypto/Signers/ClpEd25519Signer.pas
+++ b/CryptoLib/src/Crypto/Signers/ClpEd25519Signer.pas
@@ -38,6 +38,11 @@ interface
'Ed25519Signer not Initialised for Verification';
type
+ ///
+ /// Pure Ed25519 (RFC 8032) signature primitive. Buffers the message via the streaming
+ /// surface and dispatches it to the curve routines on finalisation; no
+ /// context is permitted.
+ ///
TEd25519Signer = class(TInterfacedObject, ISigner, IEd25519Signer)
strict private
@@ -76,18 +81,41 @@ TBuffer = class
function GetAlgorithmName: String; virtual;
public
+ /// Construct an uninitialised pure-Ed25519 signer; call Init before use.
constructor Create();
destructor Destroy(); override;
+ /// Initialise for signing (private key) or verification (public key).
+ ///
+ /// If is not an
+ /// (signing) or
+ /// (verification).
+ ///
procedure Init(AForSigning: Boolean;
const AParameters: ICipherParameters); virtual;
procedure Update(AInput: Byte); virtual;
procedure BlockUpdate(const ABuf: TCryptoLibByteArray;
AOff, ALength: Int32); virtual;
+ /// Length in bytes of an Ed25519 signature (64).
function GetMaxSignatureSize: Int32; virtual;
+ /// Finalise the buffered message and produce the signature. Buffer is reset on return.
+ ///
+ ///
+ /// If the signer was initialised for verification, not signing.
+ ///
function GenerateSignature(): TCryptoLibByteArray; virtual;
+ ///
+ /// Finalise the buffered message and verify . Buffer is reset on
+ /// return.
+ ///
+ /// true if the signature is valid for the accumulated message and bound public key;
+ /// otherwise false.
+ ///
+ /// If the signer was initialised for signing, not verification.
+ ///
function VerifySignature(const ASignature: TCryptoLibByteArray)
: Boolean; virtual;
+ /// Clear and rewind the buffered message.
procedure Reset(); virtual;
property AlgorithmName: String read GetAlgorithmName;
diff --git a/CryptoLib/src/Crypto/Signers/ClpEd448PhSigner.pas b/CryptoLib/src/Crypto/Signers/ClpEd448PhSigner.pas
index 2a114b53..03372c74 100644
--- a/CryptoLib/src/Crypto/Signers/ClpEd448PhSigner.pas
+++ b/CryptoLib/src/Crypto/Signers/ClpEd448PhSigner.pas
@@ -38,6 +38,10 @@ interface
SPreHashDigestFailed = 'PreHash Digest Failed';
type
+ ///
+ /// Ed448ph (RFC 8032) signature primitive: pre-hashes the message with SHAKE256 before running
+ /// pure Ed448, parameterised by a fixed context captured at construction.
+ ///
TEd448PhSigner = class(TInterfacedObject, ISigner, IEd448PhSigner)
strict private
@@ -52,18 +56,42 @@ TEd448PhSigner = class(TInterfacedObject, ISigner, IEd448PhSigner)
function GetAlgorithmName: String; virtual;
public
+ ///
+ /// Construct an Ed448ph signer bound to the supplied . The context
+ /// bytes are cloned so the caller may mutate the array afterwards; nil is treated as empty.
+ ///
constructor Create(const AContext: TCryptoLibByteArray);
destructor Destroy(); override;
+ /// Initialise for signing (private key) or verification (public key).
+ ///
+ /// If is not an
+ /// (signing) or
+ /// (verification).
+ ///
procedure Init(AForSigning: Boolean;
const AParameters: ICipherParameters); virtual;
procedure Update(AInput: Byte); virtual;
procedure BlockUpdate(const ABuf: TCryptoLibByteArray;
AOff, ALength: Int32); virtual;
+ /// Length in bytes of an Ed448ph signature (114).
function GetMaxSignatureSize: Int32; virtual;
+ /// Finalise the pre-hash and produce the signature.
+ ///
+ /// If the signer was initialised for verification, not signing, or the pre-hash finalisation
+ /// produces an unexpected length.
+ ///
function GenerateSignature(): TCryptoLibByteArray; virtual;
+ /// Finalise the pre-hash and verify .
+ /// true if the signature is valid for the accumulated message, bound public key and
+ /// captured context; otherwise false.
+ ///
+ /// If the signer was initialised for signing, not verification, or the pre-hash finalisation
+ /// produces an unexpected length.
+ ///
function VerifySignature(const ASignature: TCryptoLibByteArray)
: Boolean; virtual;
+ /// Reset the pre-hash digest; the captured context survives.
procedure Reset(); virtual;
property AlgorithmName: String read GetAlgorithmName;
diff --git a/CryptoLib/src/Crypto/Signers/ClpEd448Signer.pas b/CryptoLib/src/Crypto/Signers/ClpEd448Signer.pas
index e911631a..187bab7b 100644
--- a/CryptoLib/src/Crypto/Signers/ClpEd448Signer.pas
+++ b/CryptoLib/src/Crypto/Signers/ClpEd448Signer.pas
@@ -38,6 +38,10 @@ interface
'Ed448Signer not Initialised for Verification';
type
+ ///
+ /// Ed448 (RFC 8032) signature primitive: pure Ed448 with a mandatory domain-separation context of
+ /// up to 255 bytes captured at construction.
+ ///
TEd448Signer = class(TInterfacedObject, ISigner, IEd448Signer)
strict private
@@ -79,18 +83,44 @@ TBuffer = class
function GetAlgorithmName: String; virtual;
public
+ ///
+ /// Construct an Ed448 signer bound to the supplied . The context bytes
+ /// are cloned so the caller may mutate the array afterwards; nil is treated as empty.
+ ///
constructor Create(const AContext: TCryptoLibByteArray);
destructor Destroy(); override;
+ /// Initialise for signing (private key) or verification (public key).
+ ///
+ /// If is not an
+ /// (signing) or
+ /// (verification).
+ ///
procedure Init(AForSigning: Boolean;
const AParameters: ICipherParameters); virtual;
procedure Update(AInput: Byte); virtual;
procedure BlockUpdate(const ABuf: TCryptoLibByteArray;
AOff, ALength: Int32); virtual;
+ /// Length in bytes of an Ed448 signature (114).
function GetMaxSignatureSize: Int32; virtual;
+ /// Finalise the buffered message and produce the signature. Buffer is reset on return.
+ ///
+ ///
+ /// If the signer was initialised for verification, not signing.
+ ///
function GenerateSignature(): TCryptoLibByteArray; virtual;
+ ///
+ /// Finalise the buffered message and verify . Buffer is reset on
+ /// return.
+ ///
+ /// true if the signature is valid for the accumulated message, bound public key and
+ /// captured context; otherwise false.
+ ///
+ /// If the signer was initialised for signing, not verification.
+ ///
function VerifySignature(const ASignature: TCryptoLibByteArray)
: Boolean; virtual;
+ /// Clear and rewind the buffered message; the captured context survives.
procedure Reset(); virtual;
property AlgorithmName: String read GetAlgorithmName;
diff --git a/CryptoLib/src/Crypto/Signers/ClpSignerUtilities.pas b/CryptoLib/src/Crypto/Signers/ClpSignerUtilities.pas
index 00c233f6..f050d699 100644
--- a/CryptoLib/src/Crypto/Signers/ClpSignerUtilities.pas
+++ b/CryptoLib/src/Crypto/Signers/ClpSignerUtilities.pas
@@ -113,7 +113,6 @@ TSignerUtilities = class sealed(TObject)
class function InitSignerForMechanism(const AMechanism: String; AForSigning: Boolean;
const AKey: IAsymmetricKeyParameter; const ARandom: ISecureRandom): ISigner; static;
class procedure AddAlgorithm(const AName: String; const AOid: IDerObjectIdentifier; AIsNoRandom: Boolean); static;
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -215,22 +214,13 @@ class procedure TSignerUtilities.AddAlgorithm(const AName: String;
FNoRandom.Add(AName, 0);
end;
-class procedure TSignerUtilities.Boot;
+class constructor TSignerUtilities.Create;
begin
FAlgorithmMap := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FAlgorithmOidMap := TDictionary.Create(TAsn1Comparers.OidEqualityComparer);
FNoRandom := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
FOids := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
- TPkcsObjectIdentifiers.Boot;
- TX9ObjectIdentifiers.Boot;
- TOiwObjectIdentifiers.Boot;
- TNistObjectIdentifiers.Boot;
- TTeleTrusTObjectIdentifiers.Boot;
- TCryptoProObjectIdentifiers.Boot;
- TBsiObjectIdentifiers.Boot;
- TEdECObjectIdentifiers.Boot;
-
FAlgorithmMap.AddOrSetValue('MD2WITHRSA', 'MD2withRSA');
FAlgorithmMap.AddOrSetValue('MD2WITHRSAENCRYPTION', 'MD2withRSA');
FAlgorithmOidMap.AddOrSetValue(TPkcsObjectIdentifiers.MD2WithRsaEncryption, 'MD2withRSA');
@@ -699,11 +689,6 @@ class procedure TSignerUtilities.Boot;
AddAlgorithm('BIP340Schnorr', nil, True);
end;
-class constructor TSignerUtilities.Create;
-begin
- Boot;
-end;
-
class destructor TSignerUtilities.Destroy;
begin
FAlgorithmMap.Free;
diff --git a/CryptoLib/src/GeneralUtilities/ClpArrayUtilities.pas b/CryptoLib/src/GeneralUtilities/ClpArrayUtilities.pas
index 631dba51..14726cf2 100644
--- a/CryptoLib/src/GeneralUtilities/ClpArrayUtilities.pas
+++ b/CryptoLib/src/GeneralUtilities/ClpArrayUtilities.pas
@@ -313,7 +313,7 @@ class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibByteArray
begin
if AData = nil then
Exit(0);
- Result := HashCore(@AData[0], System.Length(AData));
+ Result := HashCore(PByte(AData), System.Length(AData));
end;
class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibByteArray;
@@ -321,21 +321,21 @@ class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibByteArray
begin
if AData = nil then
Exit(0);
- Result := HashCore(@AData[AOff], ALen);
+ Result := HashCore(PByte(AData) + AOff, ALen);
end;
class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibInt32Array): Int32;
begin
if AData = nil then
Exit(0);
- Result := HashCore(PByte(@AData[0]), System.Length(AData) * System.SizeOf(Int32));
+ Result := HashCore(PByte(PInteger(AData)), System.Length(AData) * System.SizeOf(Int32));
end;
class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibUInt32Array): Int32;
begin
if AData = nil then
Exit(0);
- Result := HashCore(PByte(@AData[0]), System.Length(AData) * System.SizeOf(UInt32));
+ Result := HashCore(PByte(PCardinal(AData)), System.Length(AData) * System.SizeOf(UInt32));
end;
class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibUInt32Array;
@@ -343,7 +343,7 @@ class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibUInt32Arr
begin
if AData = nil then
Exit(0);
- Result := HashCore(PByte(@AData[AOff]), ALen * System.SizeOf(UInt32));
+ Result := HashCore(PByte(PCardinal(AData) + AOff), ALen * System.SizeOf(UInt32));
end;
class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibUInt64Array;
@@ -351,7 +351,7 @@ class function TArrayUtilities.GetArrayHashCode(const AData: TCryptoLibUInt64Arr
begin
if AData = nil then
Exit(0);
- Result := HashCore(PByte(@AData[AOff]), ALen * System.SizeOf(UInt64));
+ Result := HashCore(PByte(PUInt64(AData) + AOff), ALen * System.SizeOf(UInt64));
end;
class function TArrayUtilities.NoZeroes(const AData: TCryptoLibByteArray): Boolean;
diff --git a/CryptoLib/src/GeneralUtilities/ClpDateTimeUtilities.pas b/CryptoLib/src/GeneralUtilities/ClpDateTimeUtilities.pas
index fab4a201..e0fddec5 100644
--- a/CryptoLib/src/GeneralUtilities/ClpDateTimeUtilities.pas
+++ b/CryptoLib/src/GeneralUtilities/ClpDateTimeUtilities.pas
@@ -269,7 +269,13 @@ class function TDateTimeParseHelper.ReadWord(
begin
Result := ReadInt(S, AIndex, ACount, LI);
if Result then
+ begin
+ // Reject negatives (e.g. "-1" parses as Int32 but is nonsense in a fixed-width field)
+ // and values that would overflow Word silently.
+ if (LI < 0) or (LI > 65535) then
+ Exit(False);
AValue := Word(LI);
+ end;
end;
class function TDateTimeParseHelper.CountFracDigits(const AFormat: String): Int32;
@@ -370,13 +376,13 @@ class function TDateTimeUtilities.DateTimeToTicks(const ADateTime: TDateTime): I
begin
// Epoch: January 1, 0001 12:00am
LEpoch := EncodeDateTime(1, 1, 1, 0, 0, 0, 0);
-
+
// Calculate milliseconds since epoch (preserving sign)
if ADateTime >= LEpoch then
LMsSinceEpoch := MilliSecondsBetween(ADateTime, LEpoch)
else
LMsSinceEpoch := -MilliSecondsBetween(ADateTime, LEpoch);
-
+
// Convert milliseconds to ticks (1 millisecond = 10,000 ticks)
Result := LMsSinceEpoch * Int64(10000);
end;
@@ -388,10 +394,10 @@ class function TDateTimeUtilities.TicksToDateTime(const ATicks: Int64): TDateTim
begin
// Epoch: January 1, 0001 12:00am
LEpoch := EncodeDateTime(1, 1, 1, 0, 0, 0, 0);
-
+
// Convert ticks to milliseconds (1 millisecond = 10,000 ticks)
LMsSinceEpoch := ATicks div Int64(10000);
-
+
// Add milliseconds to epoch to get the DateTime
Result := IncMilliSecond(LEpoch, LMsSinceEpoch);
end;
@@ -591,17 +597,33 @@ class function TDateTimeUtilities.ParseExact(
raise EFormatCryptoLibException.Create('Invalid hour');
end;
+ // --- Calendar field range checks (mirrors .NET / X.680 validation) ---
+ if (LMonth < 1) or (LMonth > 12) then
+ raise EFormatCryptoLibException.Create('Month out of range (1-12)');
+ if (LDay < 1) or (LDay > 31) then
+ raise EFormatCryptoLibException.Create('Day out of range (1-31)');
+ if LHour > 23 then
+ raise EFormatCryptoLibException.Create('Hour out of range (0-23)');
+
LMinute := 0;
LSecond := 0;
LMillisecond := 0;
if LHasMinutes then
+ begin
if not TDateTimeParseHelper.ReadWord(AStr, 7 + LYearWidth, 2, LMinute) then
raise EFormatCryptoLibException.Create('Invalid minute');
+ if LMinute > 59 then
+ raise EFormatCryptoLibException.Create('Minute out of range (0-59)');
+ end;
if LHasSeconds then
+ begin
if not TDateTimeParseHelper.ReadWord(AStr, 9 + LYearWidth, 2, LSecond) then
raise EFormatCryptoLibException.Create('Invalid second');
+ if LSecond > 59 then
+ raise EFormatCryptoLibException.Create('Second out of range (0-59)');
+ end;
// --- Fraction must be exactly where expected ---
if LHasFrac then
@@ -613,8 +635,10 @@ class function TDateTimeUtilities.ParseExact(
else
LDotExpectedPos := 7 + LYearWidth;
- if (LDotExpectedPos > LLen) or (AStr[LDotExpectedPos] <> '.') then
- raise EFormatCryptoLibException.Create('Missing fractional dot');
+ // X.680 section 46.3: both '.' and ',' are valid decimal marks
+ if (LDotExpectedPos > LLen) or
+ ((AStr[LDotExpectedPos] <> '.') and (AStr[LDotExpectedPos] <> ',')) then
+ raise EFormatCryptoLibException.Create('Missing fractional separator (. or ,)');
LFracStr := System.Copy(AStr, LDotExpectedPos + 1, LFracDigits);
if not TryStrToInt(LFracStr, LTmp) then
@@ -636,7 +660,14 @@ class function TDateTimeUtilities.ParseExact(
end;
// --- Base datetime value ---
- Result := EncodeDateTime(LYearW, LMonth, LDay, LHour, LMinute, LSecond, LMillisecond);
+ // Belt-and-suspenders: EncodeDateTime validates the combination (e.g. day 31 in
+ // a 30-day month) after our individual field range checks above.
+ try
+ Result := EncodeDateTime(LYearW, LMonth, LDay, LHour, LMinute, LSecond, LMillisecond);
+ except
+ on E: EConvertError do
+ raise EFormatCryptoLibException.Create('Invalid date/time components: ' + E.Message);
+ end;
// --- Timezone parsing if format includes zz/zzz ---
if LHasTZ3 or LHasTZ2 then
@@ -651,14 +682,14 @@ class function TDateTimeUtilities.ParseExact(
raise EFormatCryptoLibException.Create('Invalid timezone sign');
LOffsetHours := StrToIntDef(System.Copy(AStr, LSignPos + 1, 2), -1);
- if LOffsetHours < 0 then
- raise EFormatCryptoLibException.Create('Invalid timezone hours');
+ if (LOffsetHours < 0) or (LOffsetHours > 23) then
+ raise EFormatCryptoLibException.Create('Timezone hours out of range (0-23)');
if LHasTZ3 then
begin
LOffsetMinutes := StrToIntDef(System.Copy(AStr, LSignPos + 3, 2), -1);
- if LOffsetMinutes < 0 then
- raise EFormatCryptoLibException.Create('Invalid timezone minutes');
+ if (LOffsetMinutes < 0) or (LOffsetMinutes > 59) then
+ raise EFormatCryptoLibException.Create('Timezone minutes out of range (0-59)');
end
else
LOffsetMinutes := 0;
diff --git a/CryptoLib/src/Include/CryptoLib.inc b/CryptoLib/src/Include/CryptoLib.inc
index 5a99ae3c..7d7f8edd 100644
--- a/CryptoLib/src/Include/CryptoLib.inc
+++ b/CryptoLib/src/Include/CryptoLib.inc
@@ -68,17 +68,28 @@
{$DEFINE CRYPTOLIB_REQUIRES_PROPER_ALIGNMENT}
{$ENDIF}
- {$IFDEF CPUX86}
+ // CPUX86 was introduced in XE2; older Delphi versions (2010, XE) only
+ // have CPU386. On XE2+, CPUX86 alone is sufficient. The CPU386 fallback
+ // covers 2010/XE - those versions had no 64-bit compiler, so the
+ // CPU64BITS guard is harmless there (CPU64BITS itself was introduced
+ // in XE8). The guard's real purpose is DCCOSX64 (64-bit Intel macOS,
+ // available since 10.3 Rio Release 2), where Embarcadero's docs
+ // indicate CPU386 is defined alongside CPU64BITS on a 64-bit target.
+ {$IF DEFINED(CPUX86) OR (DEFINED(CPU386) AND NOT DEFINED(CPU64BITS))}
{$DEFINE CRYPTOLIB_I386}
- {$IFDEF MSWINDOWS}
- {$DEFINE CRYPTOLIB_I386_ASM}
+ {$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ {$IFDEF MSWINDOWS}
+ {$DEFINE CRYPTOLIB_I386_ASM}
+ {$ENDIF}
{$ENDIF}
- {$ENDIF}
+ {$IFEND}
{$IFDEF CPUX64}
{$DEFINE CRYPTOLIB_X86_64}
- {$IFDEF MSWINDOWS}
- {$DEFINE CRYPTOLIB_X86_64_ASM}
+ {$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ {$IFDEF MSWINDOWS}
+ {$DEFINE CRYPTOLIB_X86_64_ASM}
+ {$ENDIF}
{$ENDIF}
{$ENDIF}
diff --git a/CryptoLib/src/Include/CryptoLibFPC.inc b/CryptoLib/src/Include/CryptoLibFPC.inc
index 50fe5783..eca609de 100644
--- a/CryptoLib/src/Include/CryptoLibFPC.inc
+++ b/CryptoLib/src/Include/CryptoLibFPC.inc
@@ -47,22 +47,30 @@
{$IFDEF CPU386}
{$DEFINE CRYPTOLIB_I386}
- {$DEFINE CRYPTOLIB_I386_ASM}
+ {$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ {$DEFINE CRYPTOLIB_I386_ASM}
+ {$ENDIF}
{$ENDIF}
{$IFDEF CPUX64}
{$DEFINE CRYPTOLIB_X86_64}
- {$DEFINE CRYPTOLIB_X86_64_ASM}
+ {$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ {$DEFINE CRYPTOLIB_X86_64_ASM}
+ {$ENDIF}
{$ENDIF}
{$IFDEF CPUARM}
{$DEFINE CRYPTOLIB_ARM32}
- {$DEFINE CRYPTOLIB_ARM32_ASM}
+ {$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ {$DEFINE CRYPTOLIB_ARM32_ASM}
+ {$ENDIF}
{$ENDIF}
{$IFDEF CPUAARCH64}
{$DEFINE CRYPTOLIB_AARCH64}
- {$DEFINE CRYPTOLIB_AARCH64_ASM}
+ {$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ {$DEFINE CRYPTOLIB_AARCH64_ASM}
+ {$ENDIF}
{$ENDIF}
{================================= Target OS ==================================}
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyClmulMul2x2_i386.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyClmulMul2x2_i386.inc
new file mode 100644
index 00000000..0372015a
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyClmulMul2x2_i386.inc
@@ -0,0 +1,28 @@
+// 2x2 carryless Karatsuba multiply (3 PCLMULQDQ).
+// Entry: xmm0 = X (x0, x1), xmm1 = Y (y0, y1).
+// Exit: xmm6 = W0, xmm7 = W1 (i386 has xmm0..xmm7 only).
+// Clobbers: xmm2..xmm5.
+ movdqa xmm2, xmm0
+ punpcklqdq xmm2, xmm1
+ movdqa xmm3, xmm0
+ punpckhqdq xmm3, xmm1
+ pxor xmm2, xmm3
+
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E1, $00 // pclmulqdq xmm4, xmm1, 0
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $E9, $11 // pclmulqdq xmm5, xmm1, 17
+ movdqa xmm3, xmm2
+ db $66, $0F, $3A, $44, $DA, $01 // pclmulqdq xmm3, xmm2, 1
+
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm5
+ pxor xmm2, xmm3
+
+ movdqa xmm6, xmm2
+ pslldq xmm6, 8
+ pxor xmm6, xmm4
+
+ movdqa xmm7, xmm2
+ psrldq xmm7, 8
+ pxor xmm7, xmm5
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyClmulMul2x2_x86_64.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyClmulMul2x2_x86_64.inc
new file mode 100644
index 00000000..b17d64af
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyClmulMul2x2_x86_64.inc
@@ -0,0 +1,28 @@
+// 2x2 carryless Karatsuba multiply (3 PCLMULQDQ).
+// Entry: xmm0 = X (x0, x1), xmm1 = Y (y0, y1).
+// Exit: xmm8 = W0, xmm9 = W1.
+// Clobbers: xmm2..xmm7.
+ movdqa xmm2, xmm0
+ punpcklqdq xmm2, xmm1
+ movdqa xmm3, xmm0
+ punpckhqdq xmm3, xmm1
+ pxor xmm2, xmm3
+
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E1, $00 // pclmulqdq xmm4, xmm1, 0
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $E9, $11 // pclmulqdq xmm5, xmm1, 17
+ movdqa xmm6, xmm2
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+
+ movdqa xmm7, xmm4
+ pxor xmm7, xmm5
+ pxor xmm7, xmm6
+
+ movdqa xmm8, xmm7
+ pslldq xmm8, 8
+ pxor xmm8, xmm4
+
+ movdqa xmm9, xmm7
+ psrldq xmm9, 8
+ pxor xmm9, xmm5
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulEven_i386.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulEven_i386.inc
new file mode 100644
index 00000000..0c660b5c
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulEven_i386.inc
@@ -0,0 +1,170 @@
+// V128 BinPoly medium multiply, even limb count (i386).
+// Entry (after SimdProc4Begin_i386.inc):
+// ebx = ALen (UInt32 limb count, even), esi = PX, edi = PY, eax = PZz.
+// ZZ is addressed as packed V128 slots (16-byte stride).
+//
+// Local stack layout (after push ebp/push edx/sub esp,24):
+// [esp + 0] = L
+// [esp + 4] = last
+// [esp + 8] = zPosMax
+// [esp + 12] = zPos
+// [esp + 16] = lo
+// [esp + 20] = hi
+
+ push ebp
+ push edx
+ sub esp, 24
+
+ mov ebp, eax
+ mov edx, ebx
+ shr edx, 1
+ mov dword ptr [esp], edx // L = ALen >> 1
+
+ // Diagonal: for i = 0..L-1, ZZ[2i], ZZ[2i+1] = Mul2x2(X[i], Y[i]).
+ xor ecx, ecx
+@@BinPolyMulEvenDiagLoop:
+ cmp ecx, dword ptr [esp]
+ jge @@BinPolyMulEvenDiagDone
+
+ mov edx, ecx
+ shl edx, 4
+ movdqu xmm0, [esi + edx]
+ movdqu xmm1, [edi + edx]
+ {$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_i386.inc}
+
+ mov eax, ecx
+ shl eax, 5
+ movdqu [ebp + eax], xmm6
+ movdqu [ebp + eax + 16], xmm7
+
+ inc ecx
+ jmp @@BinPolyMulEvenDiagLoop
+@@BinPolyMulEvenDiagDone:
+
+ // Streak:
+ // V0 = ZZ[0], V1 = ZZ[1]
+ // for i = 1..L-1:
+ // V0 ^= ZZ[2i]
+ // ZZ[i] = V0 ^ V1 (overwrite)
+ // V1 ^= ZZ[2i+1]
+ movdqu xmm2, [ebp]
+ movdqu xmm3, [ebp + 16]
+ mov ecx, 1
+@@BinPolyMulEvenStreakLoop:
+ cmp ecx, dword ptr [esp]
+ jge @@BinPolyMulEvenStreakDone
+
+ mov edx, ecx
+ shl edx, 5
+ movdqu xmm4, [ebp + edx] // ZZ[2i]
+ pxor xmm2, xmm4
+
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ mov eax, ecx
+ shl eax, 4
+ movdqu [ebp + eax], xmm5 // ZZ[i] = V0 ^ V1
+
+ movdqu xmm4, [ebp + edx + 16] // ZZ[2i+1]
+ pxor xmm3, xmm4
+
+ inc ecx
+ jmp @@BinPolyMulEvenStreakLoop
+@@BinPolyMulEvenStreakDone:
+
+ // W = V0 ^ V1; ZZ[L+i] = ZZ[i] ^ W for i = 0..L-1.
+ movdqa xmm7, xmm2
+ pxor xmm7, xmm3
+ xor ecx, ecx
+@@BinPolyMulEvenFoldLoop:
+ cmp ecx, dword ptr [esp]
+ jge @@BinPolyMulEvenFoldDone
+
+ mov edx, ecx
+ shl edx, 4
+ movdqu xmm4, [ebp + edx]
+ pxor xmm4, xmm7
+
+ mov eax, dword ptr [esp]
+ add eax, ecx
+ shl eax, 4
+ movdqu [ebp + eax], xmm4
+
+ inc ecx
+ jmp @@BinPolyMulEvenFoldLoop
+@@BinPolyMulEvenFoldDone:
+
+ // Cross products:
+ // last = L-1; zPos = 1..2*last-1.
+ mov eax, dword ptr [esp]
+ dec eax
+ mov dword ptr [esp + 4], eax // last
+ cmp eax, 0
+ jle @@BinPolyMulEvenDone
+
+ mov edx, eax
+ shl edx, 1
+ dec edx
+ mov dword ptr [esp + 8], edx // zPosMax
+ mov dword ptr [esp + 12], 1 // zPos
+@@BinPolyMulEvenZPosLoop:
+ mov ecx, dword ptr [esp + 12] // zPos
+ cmp ecx, dword ptr [esp + 8]
+ jg @@BinPolyMulEvenDone
+
+ // hi = min(last, zPos)
+ mov eax, dword ptr [esp + 4] // last
+ cmp ecx, eax
+ jle @@BinPolyMulEvenSetHiFromZPos
+ mov dword ptr [esp + 20], eax
+ jmp @@BinPolyMulEvenHiDone
+@@BinPolyMulEvenSetHiFromZPos:
+ mov dword ptr [esp + 20], ecx
+@@BinPolyMulEvenHiDone:
+ mov eax, ecx
+ sub eax, dword ptr [esp + 20]
+ mov dword ptr [esp + 16], eax // lo = zPos - hi
+
+@@BinPolyMulEvenPairLoop:
+ mov ecx, dword ptr [esp + 16] // lo
+ cmp ecx, dword ptr [esp + 20] // hi
+ jge @@BinPolyMulEvenNextZPos
+
+ mov edx, ecx
+ shl edx, 4
+ mov eax, dword ptr [esp + 20]
+ shl eax, 4
+
+ movdqu xmm0, [esi + edx]
+ movdqu xmm4, [esi + eax]
+ pxor xmm0, xmm4
+ movdqu xmm1, [edi + edx]
+ movdqu xmm5, [edi + eax]
+ pxor xmm1, xmm5
+ {$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_i386.inc}
+
+ mov edx, dword ptr [esp + 12] // zPos
+ shl edx, 4
+ movdqu xmm4, [ebp + edx]
+ pxor xmm4, xmm6
+ movdqu [ebp + edx], xmm4
+ movdqu xmm4, [ebp + edx + 16]
+ pxor xmm4, xmm7
+ movdqu [ebp + edx + 16], xmm4
+
+ inc dword ptr [esp + 16] // lo++
+ dec dword ptr [esp + 20] // hi--
+ jmp @@BinPolyMulEvenPairLoop
+
+@@BinPolyMulEvenNextZPos:
+ inc dword ptr [esp + 12]
+ jmp @@BinPolyMulEvenZPosLoop
+
+@@BinPolyMulEvenDone:
+ add esp, 24
+ pop edx
+ pop ebp
+ pop edi
+ pop esi
+ pop ebx
+
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulEven_x86_64.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulEven_x86_64.inc
new file mode 100644
index 00000000..de1accfd
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulEven_x86_64.inc
@@ -0,0 +1,160 @@
+// V128 BinPoly medium multiply, even limb count (x86-64).
+// Entry (after SimdProc4Begin_x86_64.inc):
+// rcx = ALen (UInt64 limb count, even), rdx = PX, r8 = PY, r9 = PZz.
+// ZZ is addressed as packed V128 slots (16-byte stride).
+
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+
+ mov r12, rdx
+ mov r13, r8
+ mov r14, r9
+ mov r15, rcx
+ shr r15, 1 // L = ALen >> 1
+
+ // Diagonal: for i = 0..L-1, ZZ[2i], ZZ[2i+1] = Mul2x2(X[i], Y[i]).
+ xor rbx, rbx
+@@BinPolyMulEvenDiagLoop:
+ cmp rbx, r15
+ jge @@BinPolyMulEvenDiagDone
+
+ mov r10, rbx
+ shl r10, 4
+ movdqu xmm0, [r12 + r10]
+ movdqu xmm1, [r13 + r10]
+{$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_x86_64.inc}
+
+ mov r11, rbx
+ shl r11, 5
+ movdqu [r14 + r11], xmm8
+ movdqu [r14 + r11 + 16], xmm9
+
+ inc rbx
+ jmp @@BinPolyMulEvenDiagLoop
+@@BinPolyMulEvenDiagDone:
+
+ // Streak:
+ // V0 = ZZ[0], V1 = ZZ[1]
+ // for i = 1..L-1:
+ // V0 ^= ZZ[2i]
+ // ZZ[i] = V0 ^ V1 (overwrite)
+ // V1 ^= ZZ[2i+1]
+ movdqu xmm2, [r14]
+ movdqu xmm3, [r14 + 16]
+ mov rbx, 1
+@@BinPolyMulEvenStreakLoop:
+ cmp rbx, r15
+ jge @@BinPolyMulEvenStreakDone
+
+ mov r10, rbx
+ shl r10, 5
+ movdqu xmm4, [r14 + r10] // ZZ[2i]
+ pxor xmm2, xmm4
+
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ mov r11, rbx
+ shl r11, 4
+ movdqu [r14 + r11], xmm5 // ZZ[i] = V0 ^ V1
+
+ movdqu xmm4, [r14 + r10 + 16] // ZZ[2i+1]
+ pxor xmm3, xmm4
+
+ inc rbx
+ jmp @@BinPolyMulEvenStreakLoop
+@@BinPolyMulEvenStreakDone:
+
+ // W = V0 ^ V1; ZZ[L+i] = ZZ[i] ^ W for i = 0..L-1.
+ movdqa xmm7, xmm2
+ pxor xmm7, xmm3
+ xor rbx, rbx
+@@BinPolyMulEvenFoldLoop:
+ cmp rbx, r15
+ jge @@BinPolyMulEvenFoldDone
+
+ mov r10, rbx
+ shl r10, 4
+ movdqu xmm4, [r14 + r10]
+ pxor xmm4, xmm7
+
+ mov r11, r15
+ add r11, rbx
+ shl r11, 4
+ movdqu [r14 + r11], xmm4
+
+ inc rbx
+ jmp @@BinPolyMulEvenFoldLoop
+@@BinPolyMulEvenFoldDone:
+
+ // Cross products:
+ // last = L-1; zPos = 1..2*last-1.
+ mov rbp, r15
+ dec rbp // last
+ cmp rbp, 0
+ jle @@BinPolyMulEvenDone
+
+ mov rsi, rbp
+ shl rsi, 1
+ dec rsi // zPosMax = 2*last - 1
+ mov rdi, 1 // zPos
+@@BinPolyMulEvenZPosLoop:
+ cmp rdi, rsi
+ jg @@BinPolyMulEvenDone
+
+ mov rbx, rbp // hi = min(last, zPos)
+ cmp rdi, rbx
+ cmovle rbx, rdi
+ mov r10, rdi
+ sub r10, rbx // lo = zPos - hi
+
+@@BinPolyMulEvenPairLoop:
+ cmp r10, rbx
+ jge @@BinPolyMulEvenNextZPos
+
+ mov r11, r10
+ shl r11, 4
+ mov rax, rbx
+ shl rax, 4
+
+ movdqu xmm0, [r12 + r11]
+ movdqu xmm4, [r12 + rax]
+ pxor xmm0, xmm4
+ movdqu xmm1, [r13 + r11]
+ movdqu xmm5, [r13 + rax]
+ pxor xmm1, xmm5
+{$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_x86_64.inc}
+
+ mov r11, rdi
+ shl r11, 4
+ movdqu xmm4, [r14 + r11]
+ pxor xmm4, xmm8
+ movdqu [r14 + r11], xmm4
+ movdqu xmm4, [r14 + r11 + 16]
+ pxor xmm4, xmm9
+ movdqu [r14 + r11 + 16], xmm4
+
+ inc r10
+ dec rbx
+ jmp @@BinPolyMulEvenPairLoop
+
+@@BinPolyMulEvenNextZPos:
+ inc rdi
+ jmp @@BinPolyMulEvenZPosLoop
+
+@@BinPolyMulEvenDone:
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rdi
+ pop rsi
+ pop rbp
+ pop rbx
+ ret
+
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulOdd_i386.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulOdd_i386.inc
new file mode 100644
index 00000000..e649b778
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulOdd_i386.inc
@@ -0,0 +1,211 @@
+// V128 BinPoly medium multiply, odd limb count (i386).
+// Entry (after SimdProc4Begin_i386.inc):
+// ebx = ALen (UInt32 limb count, odd), esi = PX, edi = PY, eax = PZz.
+// ZZ is addressed as packed V128 slots (16-byte stride).
+//
+// Local stack layout (after push ebp/push edx/sub esp,24):
+// [esp + 0] = L
+// [esp + 4] = last
+// [esp + 8] = zPosMax
+// [esp + 12] = zPos
+// [esp + 16] = lo
+// [esp + 20] = hi
+
+ push ebp
+ push edx
+ sub esp, 24
+
+ mov ebp, eax
+ mov edx, ebx
+ shr edx, 1
+ mov dword ptr [esp], edx // L = ALen >> 1
+
+ // Diagonal full pairs: for i = 0..L-1.
+ xor ecx, ecx
+@@BinPolyMulOddDiagLoop:
+ cmp ecx, dword ptr [esp]
+ jge @@BinPolyMulOddDiagDone
+
+ mov edx, ecx
+ shl edx, 4
+ movdqu xmm0, [esi + edx]
+ movdqu xmm1, [edi + edx]
+{$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_i386.inc}
+
+ mov eax, ecx
+ shl eax, 5
+ movdqu [ebp + eax], xmm6
+ movdqu [ebp + eax + 16], xmm7
+
+ inc ecx
+ jmp @@BinPolyMulOddDiagLoop
+@@BinPolyMulOddDiagDone:
+
+ // Tail diagonal at ZZ[2L]: Mul((x[2L],0), (y[2L],0)) with pclmul imm8=0x00.
+ mov edx, dword ptr [esp]
+ shl edx, 4
+ pxor xmm0, xmm0
+ pxor xmm1, xmm1
+ movq xmm0, qword ptr [esi + edx]
+ movq xmm1, qword ptr [edi + edx]
+ db $66, $0F, $3A, $44, $C8, $00
+ mov eax, dword ptr [esp]
+ shl eax, 5
+ movdqu [ebp + eax], xmm1
+
+ // ALen = 1 special case (L = 0): only tail diagonal exists.
+ cmp dword ptr [esp], 0
+ je @@BinPolyMulOddDone
+
+ // Streak:
+ // V0 = ZZ[0], V1 = ZZ[1]
+ // for i = 1..L:
+ // V0 ^= ZZ[2i]
+ // ZZ[i] = V0 ^ V1 (overwrite)
+ // if i <> L then V1 ^= ZZ[2i+1]
+ movdqu xmm2, [ebp]
+ movdqu xmm3, [ebp + 16]
+ mov ecx, 1
+@@BinPolyMulOddStreakLoop:
+ cmp ecx, dword ptr [esp]
+ jg @@BinPolyMulOddStreakDone
+
+ mov edx, ecx
+ shl edx, 5
+ movdqu xmm4, [ebp + edx] // ZZ[2i]
+ pxor xmm2, xmm4
+
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ mov eax, ecx
+ shl eax, 4
+ movdqu [ebp + eax], xmm5 // ZZ[i] = V0 ^ V1
+
+ cmp ecx, dword ptr [esp]
+ je @@BinPolyMulOddStreakNoV1
+ movdqu xmm4, [ebp + edx + 16] // ZZ[2i+1]
+ pxor xmm3, xmm4
+@@BinPolyMulOddStreakNoV1:
+
+ inc ecx
+ jmp @@BinPolyMulOddStreakLoop
+@@BinPolyMulOddStreakDone:
+
+ // W = V0 ^ V1; ZZ[(L+1)+i] = ZZ[i] ^ W for i = 0..L-1.
+ movdqa xmm7, xmm2
+ pxor xmm7, xmm3
+ xor ecx, ecx
+@@BinPolyMulOddFoldLoop:
+ cmp ecx, dword ptr [esp]
+ jge @@BinPolyMulOddFoldDone
+
+ mov edx, ecx
+ shl edx, 4
+ movdqu xmm4, [ebp + edx]
+ pxor xmm4, xmm7
+
+ mov eax, dword ptr [esp]
+ add eax, ecx
+ inc eax
+ shl eax, 4
+ movdqu [ebp + eax], xmm4
+
+ inc ecx
+ jmp @@BinPolyMulOddFoldLoop
+@@BinPolyMulOddFoldDone:
+
+ // Cross products:
+ // last = L; zPos = 1..2*last-1, using tail vectors when hi = last.
+ mov eax, dword ptr [esp]
+ mov dword ptr [esp + 4], eax // last
+ cmp eax, 0
+ jle @@BinPolyMulOddDone
+
+ mov edx, eax
+ shl edx, 1
+ dec edx
+ mov dword ptr [esp + 8], edx // zPosMax
+ mov dword ptr [esp + 12], 1 // zPos
+@@BinPolyMulOddZPosLoop:
+ mov ecx, dword ptr [esp + 12] // zPos
+ cmp ecx, dword ptr [esp + 8]
+ jg @@BinPolyMulOddDone
+
+ // hi = min(last, zPos)
+ mov eax, dword ptr [esp + 4] // last
+ cmp ecx, eax
+ jle @@BinPolyMulOddSetHiFromZPos
+ mov dword ptr [esp + 20], eax
+ jmp @@BinPolyMulOddHiDone
+@@BinPolyMulOddSetHiFromZPos:
+ mov dword ptr [esp + 20], ecx
+@@BinPolyMulOddHiDone:
+ mov eax, ecx
+ sub eax, dword ptr [esp + 20]
+ mov dword ptr [esp + 16], eax // lo = zPos - hi
+
+@@BinPolyMulOddPairLoop:
+ mov ecx, dword ptr [esp + 16] // lo
+ cmp ecx, dword ptr [esp + 20] // hi
+ jge @@BinPolyMulOddNextZPos
+
+ // Xxor = X[lo] xor X[hi] (tail-form when hi == last).
+ mov edx, ecx
+ shl edx, 4
+ movdqu xmm0, [esi + edx]
+ mov eax, dword ptr [esp + 20] // hi
+ cmp eax, dword ptr [esp + 4] // last
+ jne @@BinPolyMulOddXHiFull
+ pxor xmm4, xmm4
+ mov eax, dword ptr [esp + 4]
+ shl eax, 4
+ movq xmm4, qword ptr [esi + eax]
+ jmp @@BinPolyMulOddXHiDone
+@@BinPolyMulOddXHiFull:
+ shl eax, 4
+ movdqu xmm4, [esi + eax]
+@@BinPolyMulOddXHiDone:
+ pxor xmm0, xmm4
+
+ // Yxor = Y[lo] xor Y[hi] (tail-form when hi == last).
+ movdqu xmm1, [edi + edx]
+ mov eax, dword ptr [esp + 20] // hi
+ cmp eax, dword ptr [esp + 4] // last
+ jne @@BinPolyMulOddYHiFull
+ pxor xmm5, xmm5
+ mov eax, dword ptr [esp + 4]
+ shl eax, 4
+ movq xmm5, qword ptr [edi + eax]
+ jmp @@BinPolyMulOddYHiDone
+@@BinPolyMulOddYHiFull:
+ shl eax, 4
+ movdqu xmm5, [edi + eax]
+@@BinPolyMulOddYHiDone:
+ pxor xmm1, xmm5
+{$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_i386.inc}
+
+ mov edx, dword ptr [esp + 12] // zPos
+ shl edx, 4
+ movdqu xmm4, [ebp + edx]
+ pxor xmm4, xmm6
+ movdqu [ebp + edx], xmm4
+ movdqu xmm4, [ebp + edx + 16]
+ pxor xmm4, xmm7
+ movdqu [ebp + edx + 16], xmm4
+
+ inc dword ptr [esp + 16] // lo++
+ dec dword ptr [esp + 20] // hi--
+ jmp @@BinPolyMulOddPairLoop
+
+@@BinPolyMulOddNextZPos:
+ inc dword ptr [esp + 12]
+ jmp @@BinPolyMulOddZPosLoop
+
+@@BinPolyMulOddDone:
+ add esp, 24
+ pop edx
+ pop ebp
+ pop edi
+ pop esi
+ pop ebx
+
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulOdd_x86_64.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulOdd_x86_64.inc
new file mode 100644
index 00000000..9e3d86f6
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulOdd_x86_64.inc
@@ -0,0 +1,201 @@
+// V128 BinPoly medium multiply, odd limb count (x86-64).
+// Entry (after SimdProc4Begin_x86_64.inc):
+// rcx = ALen (UInt64 limb count, odd), rdx = PX, r8 = PY, r9 = PZz.
+// ZZ is addressed as packed V128 slots (16-byte stride).
+
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+
+ mov r12, rdx
+ mov r13, r8
+ mov r14, r9
+ mov r15, rcx
+ shr r15, 1 // L = ALen >> 1
+
+ // Diagonal full pairs: for i = 0..L-1
+ xor rbx, rbx
+@@BinPolyMulOddDiagLoop:
+ cmp rbx, r15
+ jge @@BinPolyMulOddDiagDone
+
+ mov r10, rbx
+ shl r10, 4
+ movdqu xmm0, [r12 + r10]
+ movdqu xmm1, [r13 + r10]
+ {$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_x86_64.inc}
+
+ mov r11, rbx
+ shl r11, 5
+ movdqu [r14 + r11], xmm8
+ movdqu [r14 + r11 + 16], xmm9
+
+ inc rbx
+ jmp @@BinPolyMulOddDiagLoop
+@@BinPolyMulOddDiagDone:
+
+ // Tail diagonal at ZZ[2L]: Mul((x[2L],0), (y[2L],0)) with pclmul imm8=0x00.
+ mov r10, r15
+ shl r10, 4
+ pxor xmm0, xmm0
+ pxor xmm1, xmm1
+ movq xmm0, qword ptr [r12 + r10]
+ movq xmm1, qword ptr [r13 + r10]
+ db $66, $0F, $3A, $44, $C8, $00
+ mov r11, r15
+ shl r11, 5
+ movdqu [r14 + r11], xmm1
+
+ // ALen = 1 special case (L = 0): only tail diagonal exists.
+ cmp r15, 0
+ je @@BinPolyMulOddDone
+
+ // Streak:
+ // V0 = ZZ[0], V1 = ZZ[1]
+ // for i = 1..L:
+ // V0 ^= ZZ[2i]
+ // ZZ[i] = V0 ^ V1 (overwrite)
+ // if i <> L then V1 ^= ZZ[2i+1]
+ movdqu xmm2, [r14]
+ movdqu xmm3, [r14 + 16]
+ mov rbx, 1
+@@BinPolyMulOddStreakLoop:
+ cmp rbx, r15
+ jg @@BinPolyMulOddStreakDone
+
+ mov r10, rbx
+ shl r10, 5
+ movdqu xmm4, [r14 + r10] // ZZ[2i]
+ pxor xmm2, xmm4
+
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ mov r11, rbx
+ shl r11, 4
+ movdqu [r14 + r11], xmm5 // ZZ[i] = V0 ^ V1
+
+ cmp rbx, r15
+ je @@BinPolyMulOddStreakNoV1
+ movdqu xmm4, [r14 + r10 + 16] // ZZ[2i+1]
+ pxor xmm3, xmm4
+@@BinPolyMulOddStreakNoV1:
+
+ inc rbx
+ jmp @@BinPolyMulOddStreakLoop
+@@BinPolyMulOddStreakDone:
+
+ // W = V0 ^ V1; ZZ[(L+1)+i] = ZZ[i] ^ W for i = 0..L-1.
+ movdqa xmm7, xmm2
+ pxor xmm7, xmm3
+ xor rbx, rbx
+@@BinPolyMulOddFoldLoop:
+ cmp rbx, r15
+ jge @@BinPolyMulOddFoldDone
+
+ mov r10, rbx
+ shl r10, 4
+ movdqu xmm4, [r14 + r10]
+ pxor xmm4, xmm7
+
+ mov r11, r15
+ add r11, rbx
+ inc r11
+ shl r11, 4
+ movdqu [r14 + r11], xmm4
+
+ inc rbx
+ jmp @@BinPolyMulOddFoldLoop
+@@BinPolyMulOddFoldDone:
+
+ // Cross products:
+ // last = L; zPos = 1..2*last-1, using tail vectors when hi = last.
+ mov rbp, r15
+ cmp rbp, 0
+ jle @@BinPolyMulOddDone
+
+ mov rsi, rbp
+ shl rsi, 1
+ dec rsi // zPosMax = 2*last - 1
+ mov rdi, 1 // zPos
+@@BinPolyMulOddZPosLoop:
+ cmp rdi, rsi
+ jg @@BinPolyMulOddDone
+
+ mov rbx, rbp // hi = min(last, zPos)
+ cmp rdi, rbx
+ cmovle rbx, rdi
+ mov r10, rdi
+ sub r10, rbx // lo = zPos - hi
+
+@@BinPolyMulOddPairLoop:
+ cmp r10, rbx
+ jge @@BinPolyMulOddNextZPos
+
+ // Xxor = X[lo] xor X[hi] (tail-form when hi == last).
+ mov r11, r10
+ shl r11, 4
+ movdqu xmm0, [r12 + r11]
+ cmp rbx, rbp
+ jne @@BinPolyMulOddXHiFull
+ pxor xmm4, xmm4
+ mov rax, rbp
+ shl rax, 4
+ movq xmm4, qword ptr [r12 + rax]
+ jmp @@BinPolyMulOddXHiDone
+@@BinPolyMulOddXHiFull:
+ mov rax, rbx
+ shl rax, 4
+ movdqu xmm4, [r12 + rax]
+@@BinPolyMulOddXHiDone:
+ pxor xmm0, xmm4
+
+ // Yxor = Y[lo] xor Y[hi] (tail-form when hi == last).
+ movdqu xmm1, [r13 + r11]
+ cmp rbx, rbp
+ jne @@BinPolyMulOddYHiFull
+ pxor xmm5, xmm5
+ mov rax, rbp
+ shl rax, 4
+ movq xmm5, qword ptr [r13 + rax]
+ jmp @@BinPolyMulOddYHiDone
+@@BinPolyMulOddYHiFull:
+ mov rax, rbx
+ shl rax, 4
+ movdqu xmm5, [r13 + rax]
+@@BinPolyMulOddYHiDone:
+ pxor xmm1, xmm5
+ {$I ..\..\Include\Simd\BinPoly\BinPolyClmulMul2x2_x86_64.inc}
+
+ mov r11, rdi
+ shl r11, 4
+ movdqu xmm4, [r14 + r11]
+ pxor xmm4, xmm8
+ movdqu [r14 + r11], xmm4
+ movdqu xmm4, [r14 + r11 + 16]
+ pxor xmm4, xmm9
+ movdqu [r14 + r11 + 16], xmm4
+
+ inc r10
+ dec rbx
+ jmp @@BinPolyMulOddPairLoop
+
+@@BinPolyMulOddNextZPos:
+ inc rdi
+ jmp @@BinPolyMulOddZPosLoop
+
+@@BinPolyMulOddDone:
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rdi
+ pop rsi
+ pop rbp
+ pop rbx
+ ret
+
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulSmall_i386.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulSmall_i386.inc
new file mode 100644
index 00000000..9126e10c
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulSmall_i386.inc
@@ -0,0 +1,3101 @@
+// x86/V128 BinPoly fixed-size carryless multiply kernels for limb counts 1..10.
+// PCLMULQDQ instruction is db-encoded for broad assembler compatibility.
+// Included inside BinPolyPclmulImplMulSmall after SimdProc4Begin_i386.inc:
+// ebx = ALen, esi = PX, edi = PY, eax = PZz
+// ZZ output: V128 lane k at byte offset 16*k in PZz.
+
+ cmp ebx, 1
+ je @@BinPolySmallSize1
+ cmp ebx, 2
+ je @@BinPolySmallSize2
+ cmp ebx, 3
+ je @@BinPolySmallSize3
+ cmp ebx, 4
+ je @@BinPolySmallSize4
+ cmp ebx, 5
+ je @@BinPolySmallSize5
+ cmp ebx, 6
+ je @@BinPolySmallSize6
+ cmp ebx, 7
+ je @@BinPolySmallSize7
+ cmp ebx, 8
+ je @@BinPolySmallSize8
+ cmp ebx, 9
+ je @@BinPolySmallSize9
+ cmp ebx, 10
+ je @@BinPolySmallSize10
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize1:
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [edi + 0]
+ punpcklqdq xmm0, xmm7
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu [eax + 0], xmm1
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize2:
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [esi + 8]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [edi + 0]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm1, xmm7
+ movdqa xmm2, xmm0
+ punpcklqdq xmm2, xmm1
+ movdqa xmm3, xmm0
+ punpckhqdq xmm3, xmm1
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D1, $00 // pclmulqdq xmm2, xmm1, 0
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $D9, $11 // pclmulqdq xmm3, xmm1, 17
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm4
+ pslldq xmm0, 8
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm0
+ movdqu [eax + 0], xmm1
+ movdqu [eax + 16], xmm2
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize3:
+ sub esp, 16
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [edi + 0]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 8]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [esi + 16]
+ movq xmm7, qword ptr [edi + 16]
+ punpcklqdq xmm2, xmm7
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm4, xmm1
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm1
+ movdqu [esp + 0], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm2
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqa xmm1, xmm6
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm4
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm3
+ movdqu xmm2, [esp + 0]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm2
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm4
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm2
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqu [esp + 0], xmm2
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm1
+ psrldq xmm0, 8
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm5
+ psrldq xmm1, 8
+ movdqu xmm3, [esp + 0]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm1
+ movdqu [eax + 0], xmm2
+ movdqu [eax + 16], xmm0
+ movdqu [eax + 32], xmm4
+ add esp, 16
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize4:
+ sub esp, 64
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [esi + 8]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 16]
+ movq xmm7, qword ptr [esi + 24]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [edi + 0]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm2, xmm7
+ movq xmm3, qword ptr [edi + 16]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm3, xmm7
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqu [esp + 0], xmm4
+ movdqa xmm4, xmm0
+ punpckhqdq xmm4, xmm2
+ movdqu [esp + 16], xmm5
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E2, $00 // pclmulqdq xmm4, xmm2, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $11 // pclmulqdq xmm6, xmm2, 17
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm6
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm1
+ punpcklqdq xmm0, xmm3
+ movdqa xmm5, xmm1
+ punpckhqdq xmm5, xmm3
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C3, $00 // pclmulqdq xmm0, xmm3, 0
+ movdqa xmm5, xmm1
+ db $66, $0F, $3A, $44, $EB, $11 // pclmulqdq xmm5, xmm3, 17
+ movdqa xmm1, xmm6
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm6
+ pslldq xmm1, 8
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm1
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm0
+ movdqu xmm0, [esp + 0]
+ movdqu xmm5, [esp + 16]
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm5
+ movdqu [esp + 32], xmm1
+ movdqa xmm1, xmm0
+ punpckhqdq xmm1, xmm5
+ movdqu [esp + 48], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $CD, $00 // pclmulqdq xmm1, xmm5, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F5, $11 // pclmulqdq xmm6, xmm5, 17
+ movdqa xmm0, xmm2
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm6
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqu xmm3, [esp + 48]
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm4
+ movdqu xmm4, [esp + 32]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm5
+ movdqu [eax + 0], xmm3
+ movdqu [eax + 16], xmm2
+ movdqu [eax + 32], xmm1
+ movdqu [eax + 48], xmm4
+ add esp, 64
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize5:
+ sub esp, 176
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [edi + 0]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 8]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [esi + 16]
+ movq xmm7, qword ptr [edi + 16]
+ punpcklqdq xmm2, xmm7
+ movq xmm3, qword ptr [esi + 24]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm3, xmm7
+ movq xmm4, qword ptr [esi + 32]
+ movq xmm7, qword ptr [edi + 32]
+ punpcklqdq xmm4, xmm7
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm6, xmm1
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 0], xmm6
+ movdqa xmm6, xmm2
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm3
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 32], xmm6
+ movdqa xmm6, xmm4
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 48], xmm6
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm1
+ movdqu [esp + 64], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm2
+ movdqu [esp + 80], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqu [esp + 96], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqu [esp + 112], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqu [esp + 128], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm4
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm4
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm4
+ movdqa xmm3, xmm6
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu xmm4, [esp + 80]
+ movdqa xmm6, xmm4
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu xmm4, [esp + 96]
+ movdqu [esp + 80], xmm6
+ movdqa xmm6, xmm4
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu xmm5, [esp + 112]
+ movdqu [esp + 96], xmm4
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu xmm5, [esp + 128]
+ movdqu [esp + 112], xmm4
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu xmm0, [esp + 144]
+ movdqu [esp + 128], xmm5
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm2
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu xmm2, [esp + 64]
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm2
+ movdqu xmm3, [esp + 0]
+ movdqu [esp + 64], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm3
+ movdqu xmm1, [esp + 80]
+ movdqu [esp + 0], xmm3
+ movdqu xmm3, [esp + 64]
+ movdqu [esp + 160], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm3
+ movdqu xmm1, [esp + 16]
+ movdqu [esp + 64], xmm3
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm1
+ movdqu xmm2, [esp + 64]
+ movdqu [esp + 16], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm2
+ movdqu xmm6, [esp + 32]
+ movdqu [esp + 80], xmm3
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm6
+ movdqu xmm1, [esp + 96]
+ movdqu [esp + 32], xmm6
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm2
+ movdqu xmm1, [esp + 48]
+ movdqu [esp + 64], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqu xmm6, [esp + 112]
+ movdqu [esp + 48], xmm1
+ movdqu xmm1, [esp + 0]
+ movdqu [esp + 96], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqu xmm6, [esp + 16]
+ movdqu [esp + 0], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm6
+ movdqu xmm2, [esp + 0]
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm2
+ movdqu xmm4, [esp + 32]
+ movdqu [esp + 0], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm4
+ movdqu xmm6, [esp + 128]
+ movdqu [esp + 32], xmm4
+ movdqu xmm4, [esp + 0]
+ movdqu [esp + 112], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm4
+ movdqu xmm6, [esp + 48]
+ movdqu [esp + 0], xmm4
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm6
+ movdqu xmm2, [esp + 16]
+ movdqu [esp + 48], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 32]
+ movdqu [esp + 16], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm5
+ movdqu xmm6, [esp + 16]
+ movdqu [esp + 32], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqu xmm0, [esp + 48]
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqu xmm5, [esp + 144]
+ movdqu [esp + 48], xmm0
+ movdqu xmm0, [esp + 32]
+ movdqu [esp + 128], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqu xmm5, [esp + 48]
+ movdqu [esp + 32], xmm0
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm5
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm1
+ movdqu xmm1, [esp + 96]
+ movdqu xmm3, [esp + 112]
+ movdqu [esp + 48], xmm5
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm3
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm2
+ movdqu xmm2, [esp + 160]
+ movdqa xmm3, xmm2
+ pslldq xmm3, 8
+ movdqu xmm4, [esp + 64]
+ movdqu [esp + 112], xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm2
+ psrldq xmm3, 8
+ movdqu xmm2, [esp + 0]
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm6
+ pslldq xmm2, 8
+ movdqu xmm3, [esp + 80]
+ movdqu [esp + 0], xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm2
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqu xmm3, [esp + 16]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm1
+ psrldq xmm3, 8
+ movdqu xmm1, [esp + 32]
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm3
+ movdqu xmm1, [esp + 112]
+ movdqa xmm3, xmm1
+ pslldq xmm3, 8
+ movdqu xmm5, [esp + 128]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm6
+ movdqa xmm4, xmm1
+ psrldq xmm4, 8
+ movdqu xmm1, [esp + 48]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movdqu xmm1, [esp + 0]
+ movdqu [eax + 0], xmm1
+ movdqu [eax + 16], xmm2
+ movdqu [eax + 32], xmm0
+ movdqu [eax + 48], xmm3
+ movdqu [eax + 64], xmm5
+ add esp, 176
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize6:
+ sub esp, 160
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [edi + 0]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 8]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [esi + 16]
+ movq xmm7, qword ptr [edi + 16]
+ punpcklqdq xmm2, xmm7
+ movq xmm3, qword ptr [esi + 24]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm3, xmm7
+ movq xmm4, qword ptr [esi + 32]
+ movq xmm7, qword ptr [edi + 32]
+ punpcklqdq xmm4, xmm7
+ movq xmm5, qword ptr [esi + 40]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm5, xmm7
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 0], xmm2
+ movdqa xmm2, xmm1
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 16], xmm5
+ movdqu xmm5, [esp + 0]
+ movdqu [esp + 32], xmm1
+ movdqa xmm1, xmm5
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu [esp + 0], xmm5
+ movdqu xmm5, [esp + 32]
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm5
+ movdqu [esp + 32], xmm5
+ movdqu xmm5, [esp + 0]
+ movdqu [esp + 64], xmm3
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqu [esp + 0], xmm5
+ movdqu xmm5, [esp + 32]
+ movdqu [esp + 80], xmm0
+ movdqu xmm0, [esp + 0]
+ movdqu [esp + 96], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm0
+ movdqu [esp + 0], xmm0
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm4, xmm3
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm3, xmm1
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm6
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm6
+ movdqu xmm4, [esp + 96]
+ movdqu [esp + 32], xmm5
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm2
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm4
+ movdqa xmm1, xmm0
+ pslldq xmm1, 8
+ movdqu [esp + 96], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm1
+ movdqa xmm1, xmm0
+ psrldq xmm1, 8
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm1
+ movdqa xmm1, xmm3
+ pslldq xmm1, 8
+ movdqa xmm2, xmm5
+ pxor xmm2, xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm2
+ movdqa xmm0, xmm3
+ psrldq xmm0, 8
+ movdqu xmm2, [esp + 96]
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm0
+ movdqu xmm0, [esp + 64]
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu xmm5, [esp + 48]
+ movdqa xmm6, xmm5
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 96], xmm4
+ movdqu xmm4, [esp + 16]
+ movdqu [esp + 112], xmm3
+ movdqa xmm3, xmm4
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu [esp + 128], xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm5
+ movdqu [esp + 48], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqu [esp + 16], xmm4
+ movdqu xmm4, [esp + 48]
+ movdqu [esp + 64], xmm0
+ movdqu xmm0, [esp + 16]
+ movdqu [esp + 144], xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm0
+ movdqu [esp + 16], xmm0
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm5
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm5, xmm3
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm2
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm6
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm2
+ movdqu xmm1, [esp + 144]
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm1
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm6
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm1
+ movdqa xmm3, xmm0
+ pslldq xmm3, 8
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqa xmm2, xmm0
+ psrldq xmm2, 8
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm2
+ movdqa xmm2, xmm5
+ pslldq xmm2, 8
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm2
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm3
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqu xmm3, [esp + 144]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqu xmm0, [esp + 80]
+ movdqu xmm3, [esp + 64]
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqu xmm0, [esp + 32]
+ movdqu xmm3, [esp + 48]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm3
+ movdqu xmm0, [esp + 0]
+ movdqu xmm3, [esp + 16]
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm3
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm3, xmm6
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu [esp + 16], xmm2
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 0], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm6
+ movdqu [esp + 32], xmm2
+ movdqa xmm2, xmm5
+ pxor xmm2, xmm4
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm1
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm1, xmm2
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm0
+ movdqa xmm4, xmm5
+ pxor xmm4, xmm3
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm0
+ movdqu xmm1, [esp + 32]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm1
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm2, xmm5
+ pxor xmm2, xmm1
+ movdqa xmm5, xmm4
+ pslldq xmm5, 8
+ movdqu [esp + 32], xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm5
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm2
+ pslldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm2
+ psrldq xmm3, 8
+ movdqu xmm2, [esp + 32]
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqu xmm2, [esp + 96]
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm2
+ movdqu xmm1, [esp + 0]
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm1
+ movdqu xmm3, [esp + 128]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm3
+ movdqu xmm0, [esp + 16]
+ movdqu [esp + 96], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm0
+ movdqu xmm6, [esp + 112]
+ movdqu [esp + 16], xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm6
+ movdqu xmm4, [esp + 48]
+ movdqu [esp + 0], xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm4
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm2
+ pslldq xmm0, 8
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm2
+ psrldq xmm0, 8
+ movdqu xmm2, [esp + 0]
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm1
+ psrldq xmm0, 8
+ movdqu xmm1, [esp + 16]
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm0
+ movdqu xmm0, [esp + 96]
+ movdqu [eax + 0], xmm0
+ movdqu [eax + 16], xmm4
+ movdqu [eax + 32], xmm5
+ movdqu [eax + 48], xmm2
+ movdqu [eax + 64], xmm3
+ movdqu xmm0, [esp + 48]
+ movdqu [eax + 80], xmm0
+ add esp, 160
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize7:
+ sub esp, 176
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [esi + 8]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 16]
+ movq xmm7, qword ptr [esi + 24]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [edi + 0]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm2, xmm7
+ movq xmm3, qword ptr [edi + 16]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm3, xmm7
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqu [esp + 0], xmm4
+ movdqa xmm4, xmm0
+ punpckhqdq xmm4, xmm2
+ movdqu [esp + 16], xmm5
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E2, $00 // pclmulqdq xmm4, xmm2, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $11 // pclmulqdq xmm6, xmm2, 17
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm6
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm1
+ punpcklqdq xmm0, xmm3
+ movdqa xmm5, xmm1
+ punpckhqdq xmm5, xmm3
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C3, $00 // pclmulqdq xmm0, xmm3, 0
+ movdqa xmm5, xmm1
+ db $66, $0F, $3A, $44, $EB, $11 // pclmulqdq xmm5, xmm3, 17
+ movdqa xmm1, xmm6
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm6
+ pslldq xmm1, 8
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm1
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm0
+ movdqu xmm0, [esp + 0]
+ movdqu xmm5, [esp + 16]
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm5
+ movdqu [esp + 32], xmm2
+ movdqa xmm2, xmm0
+ punpckhqdq xmm2, xmm5
+ movdqu [esp + 48], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D5, $00 // pclmulqdq xmm2, xmm5, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F5, $11 // pclmulqdq xmm6, xmm5, 17
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm6
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqu xmm3, [esp + 32]
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm3
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm4
+ movdqu xmm4, [esp + 48]
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm4
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm5
+ movq xmm0, qword ptr [esi + 32]
+ movq xmm7, qword ptr [edi + 32]
+ punpcklqdq xmm0, xmm7
+ movq xmm5, qword ptr [esi + 40]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm5, xmm7
+ movq xmm6, qword ptr [esi + 48]
+ movq xmm7, qword ptr [edi + 48]
+ punpcklqdq xmm6, xmm7
+ movdqu [esp + 16], xmm1
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu [esp + 32], xmm3
+ movdqa xmm3, xmm5
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm6
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu [esp + 0], xmm2
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm5
+ movdqu [esp + 64], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm6
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm6
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm1
+ movdqu xmm2, [esp + 64]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm2
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm2
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqu [esp + 64], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ pslldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm4
+ psrldq xmm1, 8
+ movdqu xmm3, [esp + 64]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm1
+ movq xmm1, qword ptr [esi + 0]
+ movq xmm7, qword ptr [esi + 8]
+ punpcklqdq xmm1, xmm7
+ movq xmm3, qword ptr [esi + 32]
+ movq xmm7, qword ptr [esi + 40]
+ punpcklqdq xmm3, xmm7
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm3
+ movq xmm1, qword ptr [esi + 16]
+ movq xmm7, qword ptr [esi + 24]
+ punpcklqdq xmm1, xmm7
+ movq xmm3, qword ptr [esi + 48]
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm3
+ movq xmm1, qword ptr [edi + 0]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm1, xmm7
+ movq xmm3, qword ptr [edi + 32]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm3, xmm7
+ movdqu [esp + 64], xmm4
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm3
+ movq xmm1, qword ptr [edi + 16]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm1, xmm7
+ movq xmm3, qword ptr [edi + 48]
+ movdqu [esp + 80], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm6
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm0
+ movdqu [esp + 96], xmm2
+ movdqa xmm2, xmm5
+ punpcklqdq xmm2, xmm4
+ movdqu [esp + 112], xmm1
+ movdqa xmm1, xmm5
+ punpckhqdq xmm1, xmm4
+ movdqu [esp + 128], xmm3
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm1
+ movdqa xmm1, xmm5
+ db $66, $0F, $3A, $44, $CC, $00 // pclmulqdq xmm1, xmm4, 0
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D4, $11 // pclmulqdq xmm2, xmm4, 17
+ movdqa xmm4, xmm3
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm2
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm4
+ movdqa xmm3, xmm5
+ pslldq xmm3, 8
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm3
+ movdqa xmm1, xmm5
+ psrldq xmm1, 8
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm1
+ movdqa xmm1, xmm6
+ punpcklqdq xmm1, xmm0
+ movdqa xmm2, xmm6
+ punpckhqdq xmm2, xmm0
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm2
+ movdqa xmm1, xmm6
+ db $66, $0F, $3A, $44, $C8, $00 // pclmulqdq xmm1, xmm0, 0
+ movdqa xmm2, xmm6
+ db $66, $0F, $3A, $44, $D0, $11 // pclmulqdq xmm2, xmm0, 17
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm2
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqa xmm0, xmm6
+ pslldq xmm0, 8
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm0
+ movdqu xmm0, [esp + 112]
+ movdqu xmm2, [esp + 128]
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm0
+ punpckhqdq xmm1, xmm2
+ movdqu [esp + 160], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm1
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $CA, $00 // pclmulqdq xmm1, xmm2, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $11 // pclmulqdq xmm6, xmm2, 17
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm6
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm4
+ pslldq xmm0, 8
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm5
+ movdqu xmm3, [esp + 160]
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm4
+ movdqu xmm4, [esp + 144]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm5
+ movdqu xmm0, [esp + 0]
+ movdqu xmm5, [esp + 96]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movdqu xmm0, [esp + 48]
+ movdqu xmm5, [esp + 80]
+ movdqu [esp + 144], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm5
+ movdqu xmm0, [esp + 32]
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm0
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm5
+ movdqu xmm5, [esp + 16]
+ movdqu [esp + 160], xmm3
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm5
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm3
+ movdqu xmm3, [esp + 64]
+ movdqu [esp + 80], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm3
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm2
+ movdqu xmm2, [esp + 144]
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm2
+ movdqu [eax + 0], xmm0
+ movdqu [eax + 16], xmm5
+ movdqu xmm0, [esp + 160]
+ movdqu [eax + 32], xmm0
+ movdqu xmm0, [esp + 80]
+ movdqu [eax + 48], xmm0
+ movdqu [eax + 64], xmm1
+ movdqu [eax + 80], xmm6
+ movdqu [eax + 96], xmm3
+ add esp, 176
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize8:
+ sub esp, 192
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [esi + 8]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 16]
+ movq xmm7, qword ptr [esi + 24]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [edi + 0]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm2, xmm7
+ movq xmm3, qword ptr [edi + 16]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm3, xmm7
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqu [esp + 0], xmm4
+ movdqa xmm4, xmm0
+ punpckhqdq xmm4, xmm2
+ movdqu [esp + 16], xmm5
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E2, $00 // pclmulqdq xmm4, xmm2, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $11 // pclmulqdq xmm6, xmm2, 17
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm6
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm1
+ punpcklqdq xmm0, xmm3
+ movdqa xmm5, xmm1
+ punpckhqdq xmm5, xmm3
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C3, $00 // pclmulqdq xmm0, xmm3, 0
+ movdqa xmm5, xmm1
+ db $66, $0F, $3A, $44, $EB, $11 // pclmulqdq xmm5, xmm3, 17
+ movdqa xmm1, xmm6
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm6
+ pslldq xmm1, 8
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm1
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm0
+ movdqu xmm0, [esp + 0]
+ movdqu xmm5, [esp + 16]
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm5
+ movdqu [esp + 32], xmm2
+ movdqa xmm2, xmm0
+ punpckhqdq xmm2, xmm5
+ movdqu [esp + 48], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D5, $00 // pclmulqdq xmm2, xmm5, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F5, $11 // pclmulqdq xmm6, xmm5, 17
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm6
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqu xmm3, [esp + 32]
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm3
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm4
+ movdqu xmm4, [esp + 48]
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm4
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm5
+ movq xmm0, qword ptr [esi + 32]
+ movq xmm7, qword ptr [esi + 40]
+ punpcklqdq xmm0, xmm7
+ movq xmm5, qword ptr [esi + 48]
+ movq xmm7, qword ptr [esi + 56]
+ punpcklqdq xmm5, xmm7
+ movq xmm6, qword ptr [edi + 32]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm6, xmm7
+ movdqu [esp + 16], xmm1
+ movq xmm1, qword ptr [edi + 48]
+ movq xmm7, qword ptr [edi + 56]
+ punpcklqdq xmm1, xmm7
+ movdqu [esp + 32], xmm3
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm1
+ movdqu [esp + 0], xmm2
+ movdqa xmm2, xmm0
+ punpcklqdq xmm2, xmm6
+ movdqu [esp + 64], xmm3
+ movdqa xmm3, xmm0
+ punpckhqdq xmm3, xmm6
+ movdqu [esp + 80], xmm4
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D6, $00 // pclmulqdq xmm2, xmm6, 0
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DE, $11 // pclmulqdq xmm3, xmm6, 17
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm0
+ movdqa xmm0, xmm6
+ pslldq xmm0, 8
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm5
+ punpcklqdq xmm0, xmm1
+ movdqa xmm3, xmm5
+ punpckhqdq xmm3, xmm1
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm3
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C1, $00 // pclmulqdq xmm0, xmm1, 0
+ movdqa xmm3, xmm5
+ db $66, $0F, $3A, $44, $D9, $11 // pclmulqdq xmm3, xmm1, 17
+ movdqa xmm1, xmm6
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm6
+ pslldq xmm1, 8
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm0
+ movdqu xmm0, [esp + 64]
+ movdqu xmm3, [esp + 80]
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm3
+ movdqu [esp + 96], xmm1
+ movdqa xmm1, xmm0
+ punpckhqdq xmm1, xmm3
+ movdqu [esp + 112], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm1
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $CB, $00 // pclmulqdq xmm1, xmm3, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F3, $11 // pclmulqdq xmm6, xmm3, 17
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm6
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm4
+ pslldq xmm0, 8
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm5
+ movdqu xmm2, [esp + 112]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm2
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm4
+ movdqu xmm4, [esp + 96]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm5
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [esi + 8]
+ punpcklqdq xmm0, xmm7
+ movq xmm5, qword ptr [esi + 32]
+ movq xmm7, qword ptr [esi + 40]
+ punpcklqdq xmm5, xmm7
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movq xmm0, qword ptr [esi + 16]
+ movq xmm7, qword ptr [esi + 24]
+ punpcklqdq xmm0, xmm7
+ movq xmm5, qword ptr [esi + 48]
+ movq xmm7, qword ptr [esi + 56]
+ punpcklqdq xmm5, xmm7
+ movdqu [esp + 96], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm5
+ movq xmm0, qword ptr [edi + 0]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm0, xmm7
+ movq xmm5, qword ptr [edi + 32]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm5, xmm7
+ movdqu [esp + 80], xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm5
+ movq xmm0, qword ptr [edi + 16]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm0, xmm7
+ movq xmm5, qword ptr [edi + 48]
+ movq xmm7, qword ptr [edi + 56]
+ punpcklqdq xmm5, xmm7
+ movdqu [esp + 64], xmm3
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm4
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm3
+ movdqu [esp + 112], xmm2
+ movdqa xmm2, xmm6
+ punpcklqdq xmm2, xmm1
+ movdqu [esp + 128], xmm0
+ movdqa xmm0, xmm6
+ punpckhqdq xmm0, xmm1
+ movdqu [esp + 144], xmm5
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm6
+ db $66, $0F, $3A, $44, $C1, $00 // pclmulqdq xmm0, xmm1, 0
+ movdqa xmm2, xmm6
+ db $66, $0F, $3A, $44, $D1, $11 // pclmulqdq xmm2, xmm1, 17
+ movdqa xmm1, xmm5
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm2
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm6
+ pslldq xmm1, 8
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ punpcklqdq xmm0, xmm3
+ movdqa xmm2, xmm4
+ punpckhqdq xmm2, xmm3
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm2
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C3, $00 // pclmulqdq xmm0, xmm3, 0
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D3, $11 // pclmulqdq xmm2, xmm3, 17
+ movdqa xmm3, xmm6
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm2
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm6
+ pslldq xmm3, 8
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm3
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm0
+ movdqu xmm0, [esp + 128]
+ movdqu xmm2, [esp + 144]
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqu [esp + 160], xmm3
+ movdqa xmm3, xmm0
+ punpckhqdq xmm3, xmm2
+ movdqu [esp + 176], xmm5
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm3
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DA, $00 // pclmulqdq xmm3, xmm2, 0
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $11 // pclmulqdq xmm6, xmm2, 17
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm6
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm5
+ pslldq xmm0, 8
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm4
+ movdqu xmm1, [esp + 176]
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm1
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm4
+ movdqu xmm4, [esp + 160]
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm4
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqu xmm0, [esp + 0]
+ movdqu xmm5, [esp + 112]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movdqu xmm0, [esp + 48]
+ movdqu xmm5, [esp + 64]
+ movdqu [esp + 160], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm5
+ movdqu xmm0, [esp + 32]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm0
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm5
+ movdqu xmm5, [esp + 16]
+ movdqu [esp + 176], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm5
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm1
+ movdqu xmm1, [esp + 80]
+ movdqu [esp + 64], xmm2
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm1
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm2
+ movdqu xmm2, [esp + 160]
+ movdqu xmm6, [esp + 96]
+ movdqu [esp + 80], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm6
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm1
+ movdqu [eax + 0], xmm0
+ movdqu [eax + 16], xmm5
+ movdqu xmm0, [esp + 176]
+ movdqu [eax + 32], xmm0
+ movdqu xmm0, [esp + 64]
+ movdqu [eax + 48], xmm0
+ movdqu [eax + 64], xmm3
+ movdqu [eax + 80], xmm2
+ movdqu xmm0, [esp + 80]
+ movdqu [eax + 96], xmm0
+ movdqu [eax + 112], xmm6
+ add esp, 192
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize9:
+ sub esp, 304
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [edi + 0]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 8]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [esi + 16]
+ movq xmm7, qword ptr [edi + 16]
+ punpcklqdq xmm2, xmm7
+ movq xmm3, qword ptr [esi + 24]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm3, xmm7
+ movq xmm4, qword ptr [esi + 32]
+ movq xmm7, qword ptr [edi + 32]
+ punpcklqdq xmm4, xmm7
+ movq xmm5, qword ptr [esi + 40]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm5, xmm7
+ movq xmm6, qword ptr [esi + 48]
+ movq xmm7, qword ptr [edi + 48]
+ punpcklqdq xmm6, xmm7
+ movdqu [esp + 0], xmm5
+ movq xmm5, qword ptr [esi + 56]
+ movq xmm7, qword ptr [edi + 56]
+ punpcklqdq xmm5, xmm7
+ movdqu [esp + 16], xmm4
+ movq xmm4, qword ptr [esi + 64]
+ movq xmm7, qword ptr [edi + 64]
+ punpcklqdq xmm4, xmm7
+ movdqu [esp + 32], xmm4
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu [esp + 48], xmm5
+ movdqa xmm5, xmm1
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu [esp + 64], xmm3
+ movdqa xmm3, xmm2
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu [esp + 80], xmm6
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm1
+ movdqu [esp + 96], xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm2
+ movdqu [esp + 112], xmm2
+ movdqu xmm2, [esp + 96]
+ movdqu [esp + 128], xmm0
+ movdqu xmm0, [esp + 112]
+ movdqu [esp + 144], xmm3
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm0
+ movdqu [esp + 112], xmm0
+ movdqa xmm0, xmm6
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm6, xmm1
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm1, xmm3
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm4
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm5
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm4
+ movdqu xmm6, [esp + 144]
+ movdqu [esp + 96], xmm2
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm6
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm5
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm6
+ movdqa xmm3, xmm0
+ pslldq xmm3, 8
+ movdqu [esp + 144], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm0
+ psrldq xmm3, 8
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm1
+ pslldq xmm3, 8
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm4
+ movdqa xmm0, xmm1
+ psrldq xmm0, 8
+ movdqu xmm1, [esp + 144]
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm0
+ movdqu xmm0, [esp + 64]
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu xmm4, [esp + 16]
+ movdqa xmm5, xmm4
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu [esp + 144], xmm6
+ movdqu xmm6, [esp + 0]
+ movdqu [esp + 160], xmm3
+ movdqa xmm3, xmm6
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu [esp + 176], xmm2
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm4
+ movdqu [esp + 16], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm6
+ movdqu [esp + 0], xmm6
+ movdqu xmm6, [esp + 16]
+ movdqu [esp + 64], xmm0
+ movdqu xmm0, [esp + 0]
+ movdqu [esp + 192], xmm3
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqu [esp + 0], xmm0
+ movdqa xmm0, xmm2
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm4, xmm3
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm1
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm5
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm1
+ movdqu xmm2, [esp + 192]
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm2
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm5
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm2
+ movdqa xmm3, xmm0
+ pslldq xmm3, 8
+ movdqu [esp + 192], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm3
+ movdqa xmm1, xmm0
+ psrldq xmm1, 8
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm1
+ movdqa xmm1, xmm4
+ pslldq xmm1, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm3
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqu xmm3, [esp + 192]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqu xmm0, [esp + 80]
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu xmm5, [esp + 48]
+ movdqa xmm6, xmm5
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 192], xmm4
+ movdqu xmm4, [esp + 32]
+ movdqu [esp + 208], xmm1
+ movdqa xmm1, xmm4
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu [esp + 224], xmm2
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm5
+ movdqu [esp + 48], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqu [esp + 32], xmm4
+ movdqu xmm4, [esp + 48]
+ movdqu [esp + 80], xmm0
+ movdqu xmm0, [esp + 32]
+ movdqu [esp + 240], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm0
+ movdqu [esp + 32], xmm0
+ movdqa xmm0, xmm2
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm5, xmm1
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm3
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm6
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqu xmm2, [esp + 240]
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm2
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm6
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm2
+ movdqa xmm1, xmm0
+ pslldq xmm1, 8
+ movdqu [esp + 240], xmm2
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm1
+ movdqa xmm1, xmm0
+ psrldq xmm1, 8
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm1
+ movdqa xmm1, xmm5
+ pslldq xmm1, 8
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm3
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqu xmm3, [esp + 240]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqu xmm0, [esp + 128]
+ movdqu xmm3, [esp + 64]
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqu xmm6, [esp + 96]
+ movdqu [esp + 240], xmm4
+ movdqu xmm4, [esp + 16]
+ movdqu [esp + 256], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm4
+ movdqu [esp + 272], xmm2
+ movdqu xmm2, [esp + 112]
+ movdqu [esp + 16], xmm4
+ movdqu xmm4, [esp + 0]
+ movdqu [esp + 64], xmm3
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm4
+ movdqu [esp + 0], xmm4
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu [esp + 112], xmm2
+ movdqa xmm2, xmm1
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 96], xmm6
+ movdqa xmm6, xmm3
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 128], xmm0
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm1
+ movdqu [esp + 288], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm3
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm0, xmm6
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm3, xmm5
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm2
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqu xmm0, [esp + 288]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm2
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm0
+ movdqa xmm5, xmm1
+ pslldq xmm5, 8
+ movdqu [esp + 288], xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm5
+ movdqa xmm4, xmm1
+ psrldq xmm4, 8
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm4
+ movdqa xmm2, xmm3
+ pslldq xmm2, 8
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm4
+ movdqa xmm1, xmm3
+ psrldq xmm1, 8
+ movdqu xmm3, [esp + 288]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm1
+ movdqu xmm1, [esp + 128]
+ movdqu xmm3, [esp + 80]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm3
+ movdqu xmm1, [esp + 96]
+ movdqu xmm6, [esp + 48]
+ movdqu [esp + 128], xmm4
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm6
+ movdqu xmm1, [esp + 112]
+ movdqu [esp + 96], xmm2
+ movdqu xmm2, [esp + 32]
+ movdqu [esp + 288], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqa xmm1, xmm5
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu [esp + 32], xmm2
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 48], xmm6
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 80], xmm3
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm4
+ movdqu [esp + 112], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm3
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm3, xmm6
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm2
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm1
+ movdqu xmm3, [esp + 112]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm2
+ movdqa xmm4, xmm5
+ pxor xmm4, xmm3
+ movdqa xmm5, xmm0
+ pslldq xmm5, 8
+ movdqu [esp + 112], xmm3
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm5
+ movdqa xmm1, xmm0
+ psrldq xmm1, 8
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm1
+ movdqa xmm1, xmm4
+ pslldq xmm1, 8
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm2
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqu xmm2, [esp + 112]
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm0
+ movdqu xmm0, [esp + 64]
+ movdqu xmm2, [esp + 80]
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm2
+ movdqu xmm0, [esp + 16]
+ movdqu xmm2, [esp + 48]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm2
+ movdqu xmm0, [esp + 0]
+ movdqu xmm2, [esp + 32]
+ movdqu [esp + 48], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm2
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm6
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 32], xmm1
+ movdqa xmm1, xmm4
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu [esp + 0], xmm3
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm6
+ movdqu [esp + 16], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm4
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm3
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm3, xmm1
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm1, xmm5
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm0
+ movdqa xmm4, xmm5
+ pxor xmm4, xmm2
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm0
+ movdqu xmm3, [esp + 16]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm2
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm3
+ movdqa xmm5, xmm4
+ pslldq xmm5, 8
+ movdqu [esp + 16], xmm3
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm2
+ movdqa xmm2, xmm1
+ psrldq xmm2, 8
+ movdqu xmm1, [esp + 16]
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm2
+ movdqu xmm1, [esp + 288]
+ movdqu xmm2, [esp + 144]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm2
+ movdqu xmm1, [esp + 224]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm1
+ movdqu xmm5, [esp + 96]
+ movdqu [esp + 144], xmm2
+ movdqu xmm2, [esp + 176]
+ movdqu [esp + 224], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm2
+ movdqu xmm5, [esp + 208]
+ movdqu [esp + 96], xmm6
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm5
+ movdqu xmm1, [esp + 128]
+ movdqu [esp + 208], xmm5
+ movdqu xmm5, [esp + 160]
+ movdqu [esp + 288], xmm6
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm5
+ movdqu xmm1, [esp + 192]
+ movdqu [esp + 160], xmm5
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm1
+ movdqu xmm6, [esp + 0]
+ movdqu [esp + 192], xmm1
+ movdqu xmm1, [esp + 144]
+ movdqu [esp + 128], xmm5
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm1
+ movdqu xmm6, [esp + 272]
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm6
+ movdqu xmm5, [esp + 32]
+ movdqu [esp + 272], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 256]
+ movdqu [esp + 32], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm5
+ movdqu xmm6, [esp + 48]
+ movdqu [esp + 256], xmm5
+ movdqu xmm5, [esp + 160]
+ movdqu [esp + 0], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm5
+ movdqu xmm6, [esp + 240]
+ movdqu [esp + 160], xmm5
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm6
+ movdqu xmm1, [esp + 224]
+ movdqu [esp + 240], xmm6
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm1
+ movdqu xmm3, [esp + 272]
+ movdqu [esp + 48], xmm5
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm3
+ movdqu xmm6, [esp + 208]
+ movdqu [esp + 272], xmm3
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm6
+ movdqu xmm0, [esp + 256]
+ movdqu [esp + 16], xmm5
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm0
+ movdqu xmm3, [esp + 192]
+ movdqu [esp + 256], xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqu xmm4, [esp + 240]
+ movdqu [esp + 80], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqu xmm0, [esp + 96]
+ movdqu [esp + 240], xmm4
+ movdqa xmm4, xmm0
+ pslldq xmm4, 8
+ movdqu [esp + 64], xmm5
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm4
+ movdqa xmm2, xmm0
+ psrldq xmm2, 8
+ movdqu xmm0, [esp + 160]
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm2
+ movdqu xmm0, [esp + 288]
+ movdqa xmm2, xmm0
+ pslldq xmm2, 8
+ movdqu [esp + 160], xmm5
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm2
+ movdqu xmm2, [esp + 32]
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm2
+ movdqa xmm1, xmm0
+ psrldq xmm1, 8
+ movdqu xmm0, [esp + 128]
+ movdqa xmm2, xmm0
+ pslldq xmm2, 8
+ movdqu [esp + 288], xmm5
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm2
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm5
+ movdqu xmm2, [esp + 0]
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm2
+ movdqa xmm2, xmm0
+ psrldq xmm2, 8
+ movdqu xmm0, [esp + 16]
+ movdqa xmm5, xmm0
+ pslldq xmm5, 8
+ movdqa xmm6, xmm2
+ pxor xmm6, xmm5
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm6
+ movdqu xmm4, [esp + 48]
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm4
+ movdqa xmm3, xmm0
+ psrldq xmm3, 8
+ movdqu xmm0, [esp + 80]
+ movdqa xmm4, xmm0
+ pslldq xmm4, 8
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm4
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm6
+ movdqa xmm4, xmm0
+ psrldq xmm4, 8
+ movdqu xmm0, [esp + 64]
+ movdqa xmm5, xmm0
+ pslldq xmm5, 8
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm5
+ movdqu xmm4, [esp + 272]
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm6
+ movdqa xmm4, xmm0
+ psrldq xmm4, 8
+ movdqu xmm0, [esp + 256]
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm4
+ movdqu xmm0, [esp + 144]
+ movdqu [eax + 0], xmm0
+ movdqu xmm0, [esp + 160]
+ movdqu [eax + 16], xmm0
+ movdqu xmm0, [esp + 288]
+ movdqu [eax + 32], xmm0
+ movdqu [eax + 48], xmm1
+ movdqu [eax + 64], xmm2
+ movdqu [eax + 80], xmm3
+ movdqu [eax + 96], xmm5
+ movdqu [eax + 112], xmm6
+ movdqu xmm0, [esp + 240]
+ movdqu [eax + 128], xmm0
+ add esp, 304
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallSize10:
+ sub esp, 416
+ movq xmm0, qword ptr [esi + 0]
+ movq xmm7, qword ptr [edi + 0]
+ punpcklqdq xmm0, xmm7
+ movq xmm1, qword ptr [esi + 8]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm1, xmm7
+ movq xmm2, qword ptr [esi + 16]
+ movq xmm7, qword ptr [edi + 16]
+ punpcklqdq xmm2, xmm7
+ movq xmm3, qword ptr [esi + 24]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm3, xmm7
+ movq xmm4, qword ptr [esi + 32]
+ movq xmm7, qword ptr [edi + 32]
+ punpcklqdq xmm4, xmm7
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm6, xmm1
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 0], xmm6
+ movdqa xmm6, xmm2
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm3
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 32], xmm6
+ movdqa xmm6, xmm4
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu [esp + 48], xmm6
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm1
+ movdqu [esp + 64], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm2
+ movdqu [esp + 80], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqu [esp + 96], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqu [esp + 112], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqu [esp + 128], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm4
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm4
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm4
+ movdqa xmm3, xmm6
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu xmm4, [esp + 80]
+ movdqa xmm6, xmm4
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqu xmm4, [esp + 96]
+ movdqu [esp + 80], xmm6
+ movdqa xmm6, xmm4
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu xmm5, [esp + 112]
+ movdqu [esp + 96], xmm4
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu xmm5, [esp + 128]
+ movdqu [esp + 112], xmm4
+ movdqa xmm4, xmm5
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu xmm0, [esp + 144]
+ movdqu [esp + 128], xmm5
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm2
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu xmm2, [esp + 64]
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm2
+ movdqu xmm3, [esp + 0]
+ movdqu [esp + 64], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm3
+ movdqu xmm1, [esp + 80]
+ movdqu [esp + 0], xmm3
+ movdqu xmm3, [esp + 64]
+ movdqu [esp + 160], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm3
+ movdqu xmm1, [esp + 16]
+ movdqu [esp + 64], xmm3
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm1
+ movdqu xmm2, [esp + 64]
+ movdqu [esp + 16], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm2
+ movdqu xmm6, [esp + 32]
+ movdqu [esp + 80], xmm3
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm6
+ movdqu xmm1, [esp + 96]
+ movdqu [esp + 32], xmm6
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm2
+ movdqu xmm1, [esp + 48]
+ movdqu [esp + 64], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqu xmm6, [esp + 112]
+ movdqu [esp + 48], xmm1
+ movdqu xmm1, [esp + 0]
+ movdqu [esp + 96], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqu xmm6, [esp + 16]
+ movdqu [esp + 0], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm6
+ movdqu xmm2, [esp + 0]
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm2
+ movdqu xmm4, [esp + 32]
+ movdqu [esp + 0], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm4
+ movdqu xmm6, [esp + 128]
+ movdqu [esp + 32], xmm4
+ movdqu xmm4, [esp + 0]
+ movdqu [esp + 112], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm4
+ movdqu xmm6, [esp + 48]
+ movdqu [esp + 0], xmm4
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm6
+ movdqu xmm2, [esp + 16]
+ movdqu [esp + 48], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 32]
+ movdqu [esp + 16], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm5
+ movdqu xmm6, [esp + 16]
+ movdqu [esp + 32], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqu xmm0, [esp + 48]
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqu xmm5, [esp + 144]
+ movdqu [esp + 48], xmm0
+ movdqu xmm0, [esp + 32]
+ movdqu [esp + 128], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqu xmm5, [esp + 48]
+ movdqu [esp + 32], xmm0
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm5
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm1
+ movdqu xmm1, [esp + 96]
+ movdqu xmm3, [esp + 112]
+ movdqu [esp + 48], xmm5
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm3
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm2
+ movdqu xmm2, [esp + 160]
+ movdqa xmm3, xmm2
+ pslldq xmm3, 8
+ movdqu xmm4, [esp + 64]
+ movdqu [esp + 112], xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm2
+ psrldq xmm3, 8
+ movdqu xmm2, [esp + 0]
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm6
+ pslldq xmm2, 8
+ movdqu xmm3, [esp + 80]
+ movdqu [esp + 0], xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm2
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm6
+ psrldq xmm0, 8
+ movdqu xmm3, [esp + 16]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm1
+ psrldq xmm3, 8
+ movdqu xmm1, [esp + 32]
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm3
+ movdqu xmm1, [esp + 112]
+ movdqa xmm3, xmm1
+ pslldq xmm3, 8
+ movdqu xmm5, [esp + 128]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm6
+ movdqa xmm4, xmm1
+ psrldq xmm4, 8
+ movdqu xmm1, [esp + 48]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movq xmm1, qword ptr [esi + 40]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm1, xmm7
+ movq xmm4, qword ptr [esi + 48]
+ movq xmm7, qword ptr [edi + 48]
+ punpcklqdq xmm4, xmm7
+ movq xmm6, qword ptr [esi + 56]
+ movq xmm7, qword ptr [edi + 56]
+ punpcklqdq xmm6, xmm7
+ movdqu [esp + 48], xmm5
+ movq xmm5, qword ptr [esi + 64]
+ movq xmm7, qword ptr [edi + 64]
+ punpcklqdq xmm5, xmm7
+ movdqu [esp + 112], xmm3
+ movq xmm3, qword ptr [esi + 72]
+ movq xmm7, qword ptr [edi + 72]
+ punpcklqdq xmm3, xmm7
+ movdqu [esp + 128], xmm0
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqu [esp + 32], xmm2
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 16], xmm2
+ movdqa xmm2, xmm6
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 80], xmm2
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 160], xmm2
+ movdqa xmm2, xmm3
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 64], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm4
+ movdqu [esp + 96], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm6
+ movdqu [esp + 144], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm5
+ movdqu [esp + 176], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm6
+ movdqu [esp + 192], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm5
+ movdqu [esp + 208], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm3
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm5
+ movdqu [esp + 224], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm3
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm2
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu xmm2, [esp + 144]
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu xmm2, [esp + 176]
+ movdqu [esp + 144], xmm5
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu xmm0, [esp + 192]
+ movdqu [esp + 176], xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu xmm0, [esp + 208]
+ movdqu [esp + 192], xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqu xmm1, [esp + 224]
+ movdqu [esp + 208], xmm0
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm4
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm4, xmm6
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu xmm6, [esp + 96]
+ movdqu [esp + 224], xmm4
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm6
+ movdqu xmm3, [esp + 16]
+ movdqu [esp + 96], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqu xmm4, [esp + 144]
+ movdqu [esp + 16], xmm3
+ movdqu xmm3, [esp + 96]
+ movdqu [esp + 240], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqu xmm4, [esp + 80]
+ movdqu [esp + 96], xmm3
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm4
+ movdqu xmm6, [esp + 96]
+ movdqu [esp + 80], xmm4
+ movdqa xmm4, xmm5
+ pxor xmm4, xmm6
+ movdqu xmm5, [esp + 160]
+ movdqu [esp + 144], xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm5
+ movdqu xmm4, [esp + 176]
+ movdqu [esp + 160], xmm5
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm6
+ movdqu xmm4, [esp + 64]
+ movdqu [esp + 96], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqu xmm5, [esp + 192]
+ movdqu [esp + 64], xmm4
+ movdqu xmm4, [esp + 16]
+ movdqu [esp + 176], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqu xmm5, [esp + 80]
+ movdqu [esp + 16], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm5
+ movdqu xmm6, [esp + 16]
+ movdqu [esp + 80], xmm5
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm6
+ movdqu xmm2, [esp + 160]
+ movdqu [esp + 16], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 208]
+ movdqu [esp + 160], xmm2
+ movdqu xmm2, [esp + 16]
+ movdqu [esp + 192], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 64]
+ movdqu [esp + 16], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm5
+ movdqu xmm6, [esp + 80]
+ movdqu [esp + 64], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqu xmm0, [esp + 160]
+ movdqu [esp + 80], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqu xmm5, [esp + 80]
+ movdqu [esp + 160], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm5
+ movdqu xmm1, [esp + 64]
+ movdqu [esp + 80], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqu xmm0, [esp + 224]
+ movdqu [esp + 64], xmm1
+ movdqu xmm1, [esp + 160]
+ movdqu [esp + 208], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqu xmm0, [esp + 64]
+ movdqu [esp + 160], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm0
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm4
+ movdqu xmm3, [esp + 176]
+ movdqu xmm4, [esp + 192]
+ movdqu [esp + 64], xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm4
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm6
+ movdqu xmm2, [esp + 240]
+ movdqa xmm4, xmm2
+ pslldq xmm4, 8
+ movdqu xmm6, [esp + 96]
+ movdqu [esp + 192], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm4
+ movdqa xmm4, xmm2
+ psrldq xmm4, 8
+ movdqu xmm2, [esp + 16]
+ movdqa xmm6, xmm2
+ pxor xmm6, xmm4
+ movdqa xmm2, xmm5
+ pslldq xmm2, 8
+ movdqu xmm4, [esp + 144]
+ movdqu [esp + 16], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqa xmm1, xmm5
+ psrldq xmm1, 8
+ movdqu xmm4, [esp + 80]
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm1
+ movdqa xmm1, xmm3
+ pslldq xmm1, 8
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm4
+ movdqa xmm1, xmm3
+ psrldq xmm1, 8
+ movdqu xmm3, [esp + 160]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm1
+ movdqu xmm1, [esp + 192]
+ movdqa xmm3, xmm1
+ pslldq xmm3, 8
+ movdqu xmm5, [esp + 208]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm6
+ movdqa xmm4, xmm1
+ psrldq xmm4, 8
+ movdqu xmm1, [esp + 64]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movq xmm1, qword ptr [esi + 0]
+ movq xmm7, qword ptr [edi + 40]
+ punpcklqdq xmm1, xmm7
+ movq xmm4, qword ptr [esi + 8]
+ movq xmm7, qword ptr [edi + 48]
+ punpcklqdq xmm4, xmm7
+ movq xmm6, qword ptr [esi + 16]
+ movq xmm7, qword ptr [edi + 56]
+ punpcklqdq xmm6, xmm7
+ movdqu [esp + 64], xmm5
+ movq xmm5, qword ptr [esi + 24]
+ movq xmm7, qword ptr [edi + 64]
+ punpcklqdq xmm5, xmm7
+ movdqu [esp + 192], xmm3
+ movq xmm3, qword ptr [esi + 32]
+ movq xmm7, qword ptr [edi + 72]
+ punpcklqdq xmm3, xmm7
+ movdqu [esp + 208], xmm0
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqu [esp + 160], xmm2
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 80], xmm2
+ movdqa xmm2, xmm6
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 144], xmm2
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 240], xmm2
+ movdqa xmm2, xmm3
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 96], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm4
+ movdqu [esp + 176], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm6
+ movdqu [esp + 224], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm5
+ movdqu [esp + 256], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm6
+ movdqu [esp + 272], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm5
+ movdqu [esp + 288], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm3
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm5
+ movdqu [esp + 304], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm3
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm2
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu xmm2, [esp + 224]
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu xmm2, [esp + 256]
+ movdqu [esp + 224], xmm5
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu xmm0, [esp + 272]
+ movdqu [esp + 256], xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu xmm0, [esp + 288]
+ movdqu [esp + 272], xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqu xmm1, [esp + 304]
+ movdqu [esp + 288], xmm0
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm4
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm4, xmm6
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu xmm6, [esp + 176]
+ movdqu [esp + 304], xmm4
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm6
+ movdqu xmm3, [esp + 80]
+ movdqu [esp + 176], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqu xmm4, [esp + 224]
+ movdqu [esp + 80], xmm3
+ movdqu xmm3, [esp + 176]
+ movdqu [esp + 320], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqu xmm4, [esp + 144]
+ movdqu [esp + 176], xmm3
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm4
+ movdqu xmm6, [esp + 176]
+ movdqu [esp + 144], xmm4
+ movdqa xmm4, xmm5
+ pxor xmm4, xmm6
+ movdqu xmm5, [esp + 240]
+ movdqu [esp + 224], xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm5
+ movdqu xmm4, [esp + 256]
+ movdqu [esp + 240], xmm5
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm6
+ movdqu xmm4, [esp + 96]
+ movdqu [esp + 176], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqu xmm5, [esp + 272]
+ movdqu [esp + 96], xmm4
+ movdqu xmm4, [esp + 80]
+ movdqu [esp + 256], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqu xmm5, [esp + 144]
+ movdqu [esp + 80], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm5
+ movdqu xmm6, [esp + 80]
+ movdqu [esp + 144], xmm5
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm6
+ movdqu xmm2, [esp + 240]
+ movdqu [esp + 80], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 288]
+ movdqu [esp + 240], xmm2
+ movdqu xmm2, [esp + 80]
+ movdqu [esp + 272], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 96]
+ movdqu [esp + 80], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm5
+ movdqu xmm6, [esp + 144]
+ movdqu [esp + 96], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqu xmm0, [esp + 240]
+ movdqu [esp + 144], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqu xmm5, [esp + 144]
+ movdqu [esp + 240], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm5
+ movdqu xmm1, [esp + 96]
+ movdqu [esp + 144], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqu xmm0, [esp + 304]
+ movdqu [esp + 96], xmm1
+ movdqu xmm1, [esp + 240]
+ movdqu [esp + 288], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqu xmm0, [esp + 96]
+ movdqu [esp + 240], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm0
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm4
+ movdqu xmm3, [esp + 256]
+ movdqu xmm4, [esp + 272]
+ movdqu [esp + 96], xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm4
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm6
+ movdqu xmm2, [esp + 320]
+ movdqa xmm4, xmm2
+ pslldq xmm4, 8
+ movdqu xmm6, [esp + 176]
+ movdqu [esp + 272], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm4
+ movdqa xmm4, xmm2
+ psrldq xmm4, 8
+ movdqu xmm2, [esp + 80]
+ movdqa xmm6, xmm2
+ pxor xmm6, xmm4
+ movdqa xmm2, xmm5
+ pslldq xmm2, 8
+ movdqu xmm4, [esp + 224]
+ movdqu [esp + 80], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqa xmm1, xmm5
+ psrldq xmm1, 8
+ movdqu xmm4, [esp + 144]
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm1
+ movdqa xmm1, xmm3
+ pslldq xmm1, 8
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm4
+ movdqa xmm1, xmm3
+ psrldq xmm1, 8
+ movdqu xmm3, [esp + 240]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm1
+ movdqu xmm1, [esp + 272]
+ movdqa xmm3, xmm1
+ pslldq xmm3, 8
+ movdqu xmm5, [esp + 288]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm6
+ movdqa xmm4, xmm1
+ psrldq xmm4, 8
+ movdqu xmm1, [esp + 96]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movq xmm1, qword ptr [esi + 40]
+ movq xmm7, qword ptr [edi + 0]
+ punpcklqdq xmm1, xmm7
+ movq xmm4, qword ptr [esi + 48]
+ movq xmm7, qword ptr [edi + 8]
+ punpcklqdq xmm4, xmm7
+ movq xmm6, qword ptr [esi + 56]
+ movq xmm7, qword ptr [edi + 16]
+ punpcklqdq xmm6, xmm7
+ movdqu [esp + 96], xmm5
+ movq xmm5, qword ptr [esi + 64]
+ movq xmm7, qword ptr [edi + 24]
+ punpcklqdq xmm5, xmm7
+ movdqu [esp + 272], xmm3
+ movq xmm3, qword ptr [esi + 72]
+ movq xmm7, qword ptr [edi + 32]
+ punpcklqdq xmm3, xmm7
+ movdqu [esp + 288], xmm0
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqu [esp + 240], xmm2
+ movdqa xmm2, xmm4
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 144], xmm2
+ movdqa xmm2, xmm6
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 224], xmm2
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 320], xmm2
+ movdqa xmm2, xmm3
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu [esp + 176], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm4
+ movdqu [esp + 256], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm6
+ movdqu [esp + 304], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm5
+ movdqu [esp + 336], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm6
+ movdqu [esp + 352], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm5
+ movdqu [esp + 368], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm3
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm5
+ movdqu [esp + 384], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm3
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm2
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqu xmm2, [esp + 304]
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu xmm2, [esp + 336]
+ movdqu [esp + 304], xmm5
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu xmm0, [esp + 352]
+ movdqu [esp + 336], xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqu xmm0, [esp + 368]
+ movdqu [esp + 352], xmm2
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqu xmm1, [esp + 384]
+ movdqu [esp + 368], xmm0
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm4
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm4, xmm6
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqu xmm6, [esp + 256]
+ movdqu [esp + 384], xmm4
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm6
+ movdqu xmm3, [esp + 144]
+ movdqu [esp + 256], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqu xmm4, [esp + 304]
+ movdqu [esp + 144], xmm3
+ movdqu xmm3, [esp + 256]
+ movdqu [esp + 400], xmm6
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm3
+ movdqu xmm4, [esp + 224]
+ movdqu [esp + 256], xmm3
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm4
+ movdqu xmm6, [esp + 256]
+ movdqu [esp + 224], xmm4
+ movdqa xmm4, xmm5
+ pxor xmm4, xmm6
+ movdqu xmm5, [esp + 320]
+ movdqu [esp + 304], xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm5
+ movdqu xmm4, [esp + 336]
+ movdqu [esp + 320], xmm5
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm6
+ movdqu xmm4, [esp + 176]
+ movdqu [esp + 256], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqu xmm5, [esp + 352]
+ movdqu [esp + 176], xmm4
+ movdqu xmm4, [esp + 144]
+ movdqu [esp + 336], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqu xmm5, [esp + 224]
+ movdqu [esp + 144], xmm4
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm5
+ movdqu xmm6, [esp + 144]
+ movdqu [esp + 224], xmm5
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm6
+ movdqu xmm2, [esp + 320]
+ movdqu [esp + 144], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 368]
+ movdqu [esp + 320], xmm2
+ movdqu xmm2, [esp + 144]
+ movdqu [esp + 352], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm2
+ movdqu xmm5, [esp + 176]
+ movdqu [esp + 144], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm5
+ movdqu xmm6, [esp + 224]
+ movdqu [esp + 176], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqu xmm0, [esp + 320]
+ movdqu [esp + 224], xmm6
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm0
+ movdqu xmm5, [esp + 224]
+ movdqu [esp + 320], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm5
+ movdqu xmm1, [esp + 176]
+ movdqu [esp + 224], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqu xmm0, [esp + 384]
+ movdqu [esp + 176], xmm1
+ movdqu xmm1, [esp + 320]
+ movdqu [esp + 368], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm1
+ movdqu xmm0, [esp + 176]
+ movdqu [esp + 320], xmm1
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm0
+ movdqa xmm5, xmm3
+ pxor xmm5, xmm4
+ movdqu xmm3, [esp + 336]
+ movdqu xmm4, [esp + 352]
+ movdqu [esp + 176], xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm4
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm6
+ movdqu xmm2, [esp + 400]
+ movdqa xmm4, xmm2
+ pslldq xmm4, 8
+ movdqu xmm6, [esp + 256]
+ movdqu [esp + 352], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm4
+ movdqa xmm4, xmm2
+ psrldq xmm4, 8
+ movdqu xmm2, [esp + 144]
+ movdqa xmm6, xmm2
+ pxor xmm6, xmm4
+ movdqa xmm2, xmm5
+ pslldq xmm2, 8
+ movdqu xmm4, [esp + 304]
+ movdqu [esp + 144], xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm1
+ movdqa xmm1, xmm5
+ psrldq xmm1, 8
+ movdqu xmm4, [esp + 224]
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm1
+ movdqa xmm1, xmm3
+ pslldq xmm1, 8
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm4
+ movdqa xmm1, xmm3
+ psrldq xmm1, 8
+ movdqu xmm3, [esp + 320]
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm1
+ movdqu xmm1, [esp + 352]
+ movdqa xmm3, xmm1
+ pslldq xmm3, 8
+ movdqu xmm5, [esp + 368]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm6
+ movdqa xmm4, xmm1
+ psrldq xmm4, 8
+ movdqu xmm1, [esp + 176]
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm4
+ movdqu xmm1, [esp + 80]
+ movdqu xmm4, [esp + 144]
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm4
+ movdqu xmm1, [esp + 240]
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm2
+ movdqu xmm1, [esp + 288]
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm0
+ movdqu xmm0, [esp + 272]
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm3
+ movdqu xmm0, [esp + 96]
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm5
+ movdqu xmm0, [esp + 0]
+ movdqu [eax + 0], xmm0
+ movdqu xmm0, [esp + 32]
+ movdqu [eax + 16], xmm0
+ movdqu xmm0, [esp + 128]
+ movdqu [eax + 32], xmm0
+ movdqu xmm0, [esp + 112]
+ movdqu [eax + 48], xmm0
+ movdqu xmm0, [esp + 48]
+ movdqu [eax + 64], xmm0
+ movdqu xmm0, [esp + 16]
+ movdqu [eax + 80], xmm0
+ movdqu xmm0, [esp + 160]
+ movdqu [eax + 96], xmm0
+ movdqu xmm0, [esp + 208]
+ movdqu [eax + 112], xmm0
+ movdqu xmm0, [esp + 192]
+ movdqu [eax + 128], xmm0
+ movdqu xmm0, [esp + 64]
+ movdqu [eax + 144], xmm0
+ movdqu xmm0, [eax + 40]
+ pxor xmm0, xmm6
+ movdqu [eax + 40], xmm0
+ movdqu xmm0, [eax + 56]
+ pxor xmm0, xmm4
+ movdqu [eax + 56], xmm0
+ movdqu xmm0, [eax + 72]
+ pxor xmm0, xmm2
+ movdqu [eax + 72], xmm0
+ movdqu xmm0, [eax + 88]
+ pxor xmm0, xmm1
+ movdqu [eax + 88], xmm0
+ movdqu xmm0, [eax + 104]
+ pxor xmm0, xmm3
+ movdqu [eax + 104], xmm0
+ add esp, 416
+ jmp @@BinPolySmallDone
+
+@@BinPolySmallDone:
+ pop edi
+ pop esi
+ pop ebx
diff --git a/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulSmall_x86_64.inc b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulSmall_x86_64.inc
new file mode 100644
index 00000000..20f6e327
--- /dev/null
+++ b/CryptoLib/src/Include/Simd/BinPoly/BinPolyPclmulImplMulSmall_x86_64.inc
@@ -0,0 +1,2513 @@
+// x86/V128 BinPoly fixed-size carryless multiply kernels for limb counts 1..10.
+// PCLMULQDQ instruction is db-encoded for broad assembler compatibility.
+// Included inside BinPolyPclmulImplMulSmall after SimdProc4Begin_x86_64.inc:
+// rcx = ALen, rdx = PX, r8 = PY, r9 = PZz
+// ZZ output: V128 lane k at byte offset 16*k in PZz.
+
+ cmp rcx, 1
+ je @@BinPolySmallSize1
+ cmp rcx, 2
+ je @@BinPolySmallSize2
+ cmp rcx, 3
+ je @@BinPolySmallSize3
+ cmp rcx, 4
+ je @@BinPolySmallSize4
+ cmp rcx, 5
+ je @@BinPolySmallSize5
+ cmp rcx, 6
+ je @@BinPolySmallSize6
+ cmp rcx, 7
+ je @@BinPolySmallSize7
+ cmp rcx, 8
+ je @@BinPolySmallSize8
+ cmp rcx, 9
+ je @@BinPolySmallSize9
+ cmp rcx, 10
+ je @@BinPolySmallSize10
+ ret
+
+@@BinPolySmallSize1:
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [r8 + 0]
+ punpcklqdq xmm0, xmm15
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqu [r9 + 0], xmm1
+ ret
+
+@@BinPolySmallSize2:
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [rdx + 8]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [r8 + 0]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm1, xmm15
+ movdqa xmm2, xmm0
+ punpcklqdq xmm2, xmm1
+ movdqa xmm3, xmm0
+ punpckhqdq xmm3, xmm1
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm3
+ movdqa xmm2, xmm0
+ db $66, $0F, $3A, $44, $D1, $00 // pclmulqdq xmm2, xmm1, 0
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $D9, $11 // pclmulqdq xmm3, xmm1, 17
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm4
+ pslldq xmm0, 8
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ psrldq xmm0, 8
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm0
+ movdqu [r9 + 0], xmm1
+ movdqu [r9 + 16], xmm2
+ ret
+
+@@BinPolySmallSize3:
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [r8 + 0]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 8]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [r8 + 16]
+ punpcklqdq xmm2, xmm15
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm4, xmm1
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm2
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm1
+ movdqa xmm7, xmm0
+ pxor xmm7, xmm2
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqa xmm1, xmm6
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm2, xmm7
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm4
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm3
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm5
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm4
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqa xmm7, xmm3
+ pxor xmm7, xmm0
+ movdqa xmm0, xmm1
+ psrldq xmm0, 8
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm6
+ pslldq xmm0, 8
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm6
+ psrldq xmm1, 8
+ movdqa xmm2, xmm5
+ pxor xmm2, xmm1
+ movdqu [r9 + 0], xmm7
+ movdqu [r9 + 16], xmm0
+ movdqu [r9 + 32], xmm2
+ ret
+
+@@BinPolySmallSize4:
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [rdx + 8]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [rdx + 24]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [r8 + 0]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm2, xmm15
+ movq xmm3, qword ptr [r8 + 16]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqa xmm7, xmm0
+ punpckhqdq xmm7, xmm2
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm7
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $00 // pclmulqdq xmm6, xmm2, 0
+ movdqa xmm7, xmm0
+ db $66, $0F, $3A, $44, $FA, $11 // pclmulqdq xmm7, xmm2, 17
+ movdqa xmm0, xmm8
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm7
+ movdqa xmm8, xmm2
+ pxor xmm8, xmm0
+ movdqa xmm0, xmm8
+ pslldq xmm0, 8
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm6, xmm7
+ pxor xmm6, xmm0
+ movdqa xmm0, xmm1
+ punpcklqdq xmm0, xmm3
+ movdqa xmm7, xmm1
+ punpckhqdq xmm7, xmm3
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm7
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C3, $00 // pclmulqdq xmm0, xmm3, 0
+ movdqa xmm7, xmm1
+ db $66, $0F, $3A, $44, $FB, $11 // pclmulqdq xmm7, xmm3, 17
+ movdqa xmm1, xmm8
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm7
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm1
+ movdqa xmm1, xmm8
+ pslldq xmm1, 8
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm1
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ punpcklqdq xmm0, xmm5
+ movdqa xmm7, xmm4
+ punpckhqdq xmm7, xmm5
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm7
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C5, $00 // pclmulqdq xmm0, xmm5, 0
+ movdqa xmm7, xmm4
+ db $66, $0F, $3A, $44, $FD, $11 // pclmulqdq xmm7, xmm5, 17
+ movdqa xmm4, xmm8
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm7
+ movdqa xmm8, xmm5
+ pxor xmm8, xmm4
+ movdqa xmm4, xmm8
+ pslldq xmm4, 8
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm4, xmm7
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm2
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm1
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm3
+ movdqu [r9 + 0], xmm2
+ movdqu [r9 + 16], xmm5
+ movdqu [r9 + 32], xmm4
+ movdqu [r9 + 48], xmm1
+ ret
+
+@@BinPolySmallSize5:
+ sub rsp, 48
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [r8 + 0]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 8]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [r8 + 16]
+ punpcklqdq xmm2, xmm15
+ movq xmm3, qword ptr [rdx + 24]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movq xmm4, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [r8 + 32]
+ punpcklqdq xmm4, xmm15
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm6, xmm1
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm7, xmm2
+ db $66, $0F, $3A, $44, $FF, $01 // pclmulqdq xmm7, xmm7, 1
+ movdqa xmm8, xmm3
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm9, xmm4
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm1
+ movdqa xmm11, xmm0
+ pxor xmm11, xmm2
+ movdqa xmm12, xmm0
+ pxor xmm12, xmm3
+ movdqa xmm13, xmm0
+ pxor xmm13, xmm4
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqa xmm14, xmm1
+ pxor xmm14, xmm3
+ movdqu [rsp + 0], xmm9
+ movdqa xmm9, xmm1
+ pxor xmm9, xmm4
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqu [rsp + 16], xmm8
+ movdqa xmm8, xmm2
+ pxor xmm8, xmm4
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm4
+ movdqa xmm3, xmm10
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm4, xmm11
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm10, xmm12
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm13
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm0
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm0, xmm14
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm13, xmm9
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm9, xmm1
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm1, xmm8
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm8, xmm2
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm5
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm6
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm5
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm7
+ movdqa xmm2, xmm10
+ pxor xmm2, xmm5
+ movdqu xmm10, [rsp + 16]
+ movdqa xmm14, xmm2
+ pxor xmm14, xmm10
+ movdqa xmm2, xmm11
+ pxor xmm2, xmm5
+ movdqu xmm11, [rsp + 0]
+ movdqu [rsp + 16], xmm10
+ movdqa xmm10, xmm2
+ pxor xmm10, xmm11
+ movdqa xmm2, xmm12
+ pxor xmm2, xmm6
+ movdqa xmm12, xmm2
+ pxor xmm12, xmm7
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm6
+ movdqu xmm0, [rsp + 16]
+ movdqu [rsp + 0], xmm11
+ movdqa xmm11, xmm2
+ pxor xmm11, xmm0
+ movdqa xmm2, xmm13
+ pxor xmm2, xmm6
+ movdqu xmm13, [rsp + 0]
+ movdqu [rsp + 16], xmm0
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm13
+ movdqa xmm2, xmm9
+ pxor xmm2, xmm7
+ movdqu xmm9, [rsp + 16]
+ movdqu [rsp + 0], xmm13
+ movdqa xmm13, xmm2
+ pxor xmm13, xmm9
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm7
+ movdqu xmm1, [rsp + 0]
+ movdqu [rsp + 16], xmm9
+ movdqa xmm9, xmm2
+ pxor xmm9, xmm1
+ movdqu xmm2, [rsp + 16]
+ movdqu [rsp + 0], xmm1
+ movdqa xmm1, xmm8
+ pxor xmm1, xmm2
+ movdqu xmm8, [rsp + 0]
+ movdqu [rsp + 32], xmm9
+ movdqa xmm9, xmm1
+ pxor xmm9, xmm8
+ movdqa xmm1, xmm14
+ pxor xmm1, xmm12
+ movdqa xmm12, xmm10
+ pxor xmm12, xmm11
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm13
+ movdqa xmm0, xmm3
+ pslldq xmm0, 8
+ movdqa xmm11, xmm5
+ pxor xmm11, xmm0
+ movdqa xmm0, xmm3
+ psrldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm5
+ movdqa xmm3, xmm1
+ psrldq xmm3, 8
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm3
+ movdqa xmm3, xmm10
+ pslldq xmm3, 8
+ movdqa xmm4, xmm12
+ pxor xmm4, xmm3
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm4
+ movdqa xmm1, xmm10
+ psrldq xmm1, 8
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm1
+ movdqa xmm1, xmm9
+ pslldq xmm1, 8
+ movdqu xmm2, [rsp + 32]
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm5
+ movdqa xmm2, xmm9
+ psrldq xmm2, 8
+ movdqa xmm4, xmm8
+ pxor xmm4, xmm2
+ movdqu [r9 + 0], xmm11
+ movdqu [r9 + 16], xmm0
+ movdqu [r9 + 32], xmm3
+ movdqu [r9 + 48], xmm1
+ movdqu [r9 + 64], xmm4
+ add rsp, 48
+ ret
+
+@@BinPolySmallSize6:
+ sub rsp, 32
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [r8 + 0]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 8]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [r8 + 16]
+ punpcklqdq xmm2, xmm15
+ movq xmm3, qword ptr [rdx + 24]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movq xmm4, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [r8 + 32]
+ punpcklqdq xmm4, xmm15
+ movq xmm5, qword ptr [rdx + 40]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm5, xmm15
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm7, xmm1
+ db $66, $0F, $3A, $44, $FF, $01 // pclmulqdq xmm7, xmm7, 1
+ movdqa xmm8, xmm2
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm1
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm2
+ movdqa xmm11, xmm1
+ pxor xmm11, xmm2
+ movdqa xmm12, xmm9
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm9, xmm10
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm11
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm12
+ pxor xmm11, xmm6
+ movdqa xmm12, xmm11
+ pxor xmm12, xmm7
+ movdqa xmm11, xmm9
+ pxor xmm11, xmm6
+ movdqa xmm9, xmm11
+ pxor xmm9, xmm8
+ movdqa xmm11, xmm10
+ pxor xmm11, xmm7
+ movdqa xmm10, xmm11
+ pxor xmm10, xmm8
+ movdqa xmm11, xmm12
+ pslldq xmm11, 8
+ movdqa xmm13, xmm6
+ pxor xmm13, xmm11
+ movdqa xmm6, xmm12
+ psrldq xmm6, 8
+ movdqa xmm11, xmm7
+ pxor xmm11, xmm6
+ movdqa xmm6, xmm10
+ pslldq xmm6, 8
+ movdqa xmm7, xmm9
+ pxor xmm7, xmm6
+ movdqa xmm6, xmm11
+ pxor xmm6, xmm7
+ movdqa xmm7, xmm10
+ psrldq xmm7, 8
+ movdqa xmm9, xmm8
+ pxor xmm9, xmm7
+ movdqa xmm7, xmm3
+ db $66, $0F, $3A, $44, $FF, $01 // pclmulqdq xmm7, xmm7, 1
+ movdqa xmm8, xmm4
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm10, xmm5
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm3
+ pxor xmm11, xmm4
+ movdqa xmm12, xmm3
+ pxor xmm12, xmm5
+ movdqa xmm14, xmm4
+ pxor xmm14, xmm5
+ movdqu [rsp + 0], xmm13
+ movdqa xmm13, xmm11
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm11, xmm12
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm14
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm14, xmm13
+ pxor xmm14, xmm7
+ movdqa xmm13, xmm14
+ pxor xmm13, xmm8
+ movdqa xmm14, xmm11
+ pxor xmm14, xmm7
+ movdqa xmm11, xmm14
+ pxor xmm11, xmm10
+ movdqa xmm14, xmm12
+ pxor xmm14, xmm8
+ movdqa xmm12, xmm14
+ pxor xmm12, xmm10
+ movdqa xmm14, xmm13
+ pslldq xmm14, 8
+ movdqu [rsp + 16], xmm9
+ movdqa xmm9, xmm7
+ pxor xmm9, xmm14
+ movdqa xmm7, xmm13
+ psrldq xmm7, 8
+ movdqa xmm13, xmm8
+ pxor xmm13, xmm7
+ movdqa xmm7, xmm12
+ pslldq xmm7, 8
+ movdqa xmm8, xmm11
+ pxor xmm8, xmm7
+ movdqa xmm7, xmm13
+ pxor xmm7, xmm8
+ movdqa xmm8, xmm12
+ psrldq xmm8, 8
+ movdqa xmm11, xmm10
+ pxor xmm11, xmm8
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm3
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm4
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm5
+ movdqa xmm2, xmm8
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm4, xmm1
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm8
+ pxor xmm5, xmm0
+ movdqa xmm10, xmm8
+ pxor xmm10, xmm1
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm1
+ movdqa xmm0, xmm5
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm1, xmm10
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm5, xmm8
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm2
+ movdqa xmm0, xmm8
+ pxor xmm0, xmm3
+ movdqa xmm8, xmm1
+ pxor xmm8, xmm2
+ movdqa xmm1, xmm8
+ pxor xmm1, xmm4
+ movdqa xmm8, xmm5
+ pxor xmm8, xmm3
+ movdqa xmm5, xmm8
+ pxor xmm5, xmm4
+ movdqa xmm8, xmm0
+ pslldq xmm8, 8
+ movdqa xmm10, xmm2
+ pxor xmm10, xmm8
+ movdqa xmm2, xmm0
+ psrldq xmm2, 8
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm2
+ movdqa xmm2, xmm5
+ pslldq xmm2, 8
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm2
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm3
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm0
+ movdqu xmm0, [rsp + 0]
+ movdqa xmm3, xmm10
+ pxor xmm3, xmm0
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm9
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm6
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm7
+ movdqu xmm3, [rsp + 16]
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm2, xmm5
+ pxor xmm2, xmm11
+ movdqa xmm5, xmm4
+ pslldq xmm5, 8
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm5
+ movdqa xmm5, xmm4
+ psrldq xmm5, 8
+ movdqa xmm4, xmm3
+ pxor xmm4, xmm5
+ movdqa xmm3, xmm1
+ pslldq xmm3, 8
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm3
+ movdqa xmm3, xmm1
+ psrldq xmm3, 8
+ movdqa xmm1, xmm9
+ pxor xmm1, xmm3
+ movdqa xmm3, xmm2
+ pslldq xmm3, 8
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm3
+ movdqa xmm1, xmm2
+ psrldq xmm1, 8
+ movdqa xmm2, xmm7
+ pxor xmm2, xmm1
+ movdqu [r9 + 0], xmm0
+ movdqu [r9 + 16], xmm8
+ movdqu [r9 + 32], xmm5
+ movdqu [r9 + 48], xmm4
+ movdqu [r9 + 64], xmm2
+ movdqu [r9 + 80], xmm11
+ add rsp, 32
+ ret
+
+@@BinPolySmallSize7:
+ sub rsp, 16
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [rdx + 8]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [rdx + 24]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [r8 + 0]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm2, xmm15
+ movq xmm3, qword ptr [r8 + 16]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqa xmm7, xmm0
+ punpckhqdq xmm7, xmm2
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm7
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $00 // pclmulqdq xmm6, xmm2, 0
+ movdqa xmm7, xmm0
+ db $66, $0F, $3A, $44, $FA, $11 // pclmulqdq xmm7, xmm2, 17
+ movdqa xmm0, xmm8
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm7
+ movdqa xmm8, xmm2
+ pxor xmm8, xmm0
+ movdqa xmm0, xmm8
+ pslldq xmm0, 8
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm6, xmm7
+ pxor xmm6, xmm0
+ movdqa xmm0, xmm1
+ punpcklqdq xmm0, xmm3
+ movdqa xmm7, xmm1
+ punpckhqdq xmm7, xmm3
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm7
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C3, $00 // pclmulqdq xmm0, xmm3, 0
+ movdqa xmm7, xmm1
+ db $66, $0F, $3A, $44, $FB, $11 // pclmulqdq xmm7, xmm3, 17
+ movdqa xmm1, xmm8
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm7
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm1
+ movdqa xmm1, xmm8
+ pslldq xmm1, 8
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm1
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ punpcklqdq xmm0, xmm5
+ movdqa xmm7, xmm4
+ punpckhqdq xmm7, xmm5
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm7
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C5, $00 // pclmulqdq xmm0, xmm5, 0
+ movdqa xmm7, xmm4
+ db $66, $0F, $3A, $44, $FD, $11 // pclmulqdq xmm7, xmm5, 17
+ movdqa xmm4, xmm8
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm7
+ movdqa xmm8, xmm5
+ pxor xmm8, xmm4
+ movdqa xmm4, xmm8
+ pslldq xmm4, 8
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm4, xmm7
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm2
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm1
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm3
+ movq xmm0, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [r8 + 32]
+ punpcklqdq xmm0, xmm15
+ movq xmm3, qword ptr [rdx + 40]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm3, xmm15
+ movq xmm6, qword ptr [rdx + 48]
+ movq xmm15, qword ptr [r8 + 48]
+ punpcklqdq xmm6, xmm15
+ movdqa xmm7, xmm0
+ db $66, $0F, $3A, $44, $FF, $01 // pclmulqdq xmm7, xmm7, 1
+ movdqa xmm8, xmm3
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm9, xmm6
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm3
+ movdqa xmm11, xmm0
+ pxor xmm11, xmm6
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm6
+ movdqa xmm3, xmm10
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm6, xmm11
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm10, xmm0
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm7
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm8
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm7
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm9
+ movdqa xmm0, xmm10
+ pxor xmm0, xmm8
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm9
+ movdqa xmm0, xmm3
+ pslldq xmm0, 8
+ movdqa xmm11, xmm7
+ pxor xmm11, xmm0
+ movdqa xmm0, xmm3
+ psrldq xmm0, 8
+ movdqa xmm3, xmm8
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm10
+ pslldq xmm0, 8
+ movdqa xmm7, xmm6
+ pxor xmm7, xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm7
+ movdqa xmm3, xmm10
+ psrldq xmm3, 8
+ movdqa xmm6, xmm9
+ pxor xmm6, xmm3
+ movq xmm3, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [rdx + 8]
+ punpcklqdq xmm3, xmm15
+ movq xmm7, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [rdx + 40]
+ punpcklqdq xmm7, xmm15
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm7
+ movq xmm3, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [rdx + 24]
+ punpcklqdq xmm3, xmm15
+ movq xmm7, qword ptr [rdx + 48]
+ movdqa xmm9, xmm3
+ pxor xmm9, xmm7
+ movq xmm3, qword ptr [r8 + 0]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm3, xmm15
+ movq xmm7, qword ptr [r8 + 32]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm7, xmm15
+ movdqa xmm10, xmm3
+ pxor xmm10, xmm7
+ movq xmm3, qword ptr [r8 + 16]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movq xmm7, qword ptr [r8 + 48]
+ movdqa xmm12, xmm3
+ pxor xmm12, xmm7
+ movdqa xmm3, xmm8
+ pxor xmm3, xmm9
+ movdqa xmm7, xmm10
+ pxor xmm7, xmm12
+ movdqa xmm13, xmm8
+ punpcklqdq xmm13, xmm10
+ movdqa xmm14, xmm8
+ punpckhqdq xmm14, xmm10
+ movdqu [rsp + 0], xmm6
+ movdqa xmm6, xmm13
+ pxor xmm6, xmm14
+ movdqa xmm13, xmm8
+ db $66, $45, $0F, $3A, $44, $EA, $00 // pclmulqdq xmm13, xmm10, 0
+ movdqa xmm14, xmm8
+ db $66, $45, $0F, $3A, $44, $F2, $11 // pclmulqdq xmm14, xmm10, 17
+ movdqa xmm8, xmm6
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm6, xmm13
+ pxor xmm6, xmm14
+ movdqa xmm10, xmm6
+ pxor xmm10, xmm8
+ movdqa xmm6, xmm10
+ pslldq xmm6, 8
+ movdqa xmm8, xmm13
+ pxor xmm8, xmm6
+ movdqa xmm6, xmm10
+ psrldq xmm6, 8
+ movdqa xmm10, xmm14
+ pxor xmm10, xmm6
+ movdqa xmm6, xmm9
+ punpcklqdq xmm6, xmm12
+ movdqa xmm13, xmm9
+ punpckhqdq xmm13, xmm12
+ movdqa xmm14, xmm6
+ pxor xmm14, xmm13
+ movdqa xmm6, xmm9
+ db $66, $41, $0F, $3A, $44, $F4, $00 // pclmulqdq xmm6, xmm12, 0
+ movdqa xmm13, xmm9
+ db $66, $45, $0F, $3A, $44, $EC, $11 // pclmulqdq xmm13, xmm12, 17
+ movdqa xmm9, xmm14
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm12, xmm6
+ pxor xmm12, xmm13
+ movdqa xmm14, xmm12
+ pxor xmm14, xmm9
+ movdqa xmm9, xmm14
+ pslldq xmm9, 8
+ movdqa xmm12, xmm6
+ pxor xmm12, xmm9
+ movdqa xmm6, xmm14
+ psrldq xmm6, 8
+ movdqa xmm9, xmm13
+ pxor xmm9, xmm6
+ movdqa xmm6, xmm3
+ punpcklqdq xmm6, xmm7
+ movdqa xmm13, xmm3
+ punpckhqdq xmm13, xmm7
+ movdqa xmm14, xmm6
+ pxor xmm14, xmm13
+ movdqa xmm6, xmm3
+ db $66, $0F, $3A, $44, $F7, $00 // pclmulqdq xmm6, xmm7, 0
+ movdqa xmm13, xmm3
+ db $66, $44, $0F, $3A, $44, $EF, $11 // pclmulqdq xmm13, xmm7, 17
+ movdqa xmm3, xmm14
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm7, xmm6
+ pxor xmm7, xmm13
+ movdqa xmm14, xmm7
+ pxor xmm14, xmm3
+ movdqa xmm3, xmm14
+ pslldq xmm3, 8
+ movdqa xmm7, xmm6
+ pxor xmm7, xmm3
+ movdqa xmm3, xmm14
+ psrldq xmm3, 8
+ movdqa xmm6, xmm13
+ pxor xmm6, xmm3
+ movdqa xmm3, xmm10
+ pxor xmm3, xmm12
+ movdqa xmm10, xmm7
+ pxor xmm10, xmm8
+ movdqa xmm7, xmm3
+ pxor xmm7, xmm10
+ movdqa xmm10, xmm6
+ pxor xmm10, xmm9
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm10
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm11
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm8
+ pxor xmm0, xmm2
+ movdqa xmm1, xmm3
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm7
+ pxor xmm0, xmm5
+ movdqa xmm7, xmm4
+ pxor xmm7, xmm0
+ movdqu xmm0, [rsp + 0]
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm0
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm8
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm9
+ movdqu [r9 + 0], xmm2
+ movdqu [r9 + 16], xmm5
+ movdqu [r9 + 32], xmm1
+ movdqu [r9 + 48], xmm7
+ movdqu [r9 + 64], xmm6
+ movdqu [r9 + 80], xmm3
+ movdqu [r9 + 96], xmm0
+ add rsp, 16
+ ret
+
+@@BinPolySmallSize8:
+ sub rsp, 32
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [rdx + 8]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [rdx + 24]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [r8 + 0]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm2, xmm15
+ movq xmm3, qword ptr [r8 + 16]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm1
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm3
+ movdqa xmm6, xmm0
+ punpcklqdq xmm6, xmm2
+ movdqa xmm7, xmm0
+ punpckhqdq xmm7, xmm2
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm7
+ movdqa xmm6, xmm0
+ db $66, $0F, $3A, $44, $F2, $00 // pclmulqdq xmm6, xmm2, 0
+ movdqa xmm7, xmm0
+ db $66, $0F, $3A, $44, $FA, $11 // pclmulqdq xmm7, xmm2, 17
+ movdqa xmm0, xmm8
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm7
+ movdqa xmm8, xmm2
+ pxor xmm8, xmm0
+ movdqa xmm0, xmm8
+ pslldq xmm0, 8
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm6, xmm7
+ pxor xmm6, xmm0
+ movdqa xmm0, xmm1
+ punpcklqdq xmm0, xmm3
+ movdqa xmm7, xmm1
+ punpckhqdq xmm7, xmm3
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm7
+ movdqa xmm0, xmm1
+ db $66, $0F, $3A, $44, $C3, $00 // pclmulqdq xmm0, xmm3, 0
+ movdqa xmm7, xmm1
+ db $66, $0F, $3A, $44, $FB, $11 // pclmulqdq xmm7, xmm3, 17
+ movdqa xmm1, xmm8
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm7
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm1
+ movdqa xmm1, xmm8
+ pslldq xmm1, 8
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm1
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm4
+ punpcklqdq xmm0, xmm5
+ movdqa xmm7, xmm4
+ punpckhqdq xmm7, xmm5
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm7
+ movdqa xmm0, xmm4
+ db $66, $0F, $3A, $44, $C5, $00 // pclmulqdq xmm0, xmm5, 0
+ movdqa xmm7, xmm4
+ db $66, $0F, $3A, $44, $FD, $11 // pclmulqdq xmm7, xmm5, 17
+ movdqa xmm4, xmm8
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm7
+ movdqa xmm8, xmm5
+ pxor xmm8, xmm4
+ movdqa xmm4, xmm8
+ pslldq xmm4, 8
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm4
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm4, xmm7
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm3
+ movdqa xmm3, xmm5
+ pxor xmm3, xmm2
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm1
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm3
+ movq xmm0, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [rdx + 40]
+ punpcklqdq xmm0, xmm15
+ movq xmm3, qword ptr [rdx + 48]
+ movq xmm15, qword ptr [rdx + 56]
+ punpcklqdq xmm3, xmm15
+ movq xmm6, qword ptr [r8 + 32]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm6, xmm15
+ movq xmm7, qword ptr [r8 + 48]
+ movq xmm15, qword ptr [r8 + 56]
+ punpcklqdq xmm7, xmm15
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm3
+ movdqa xmm9, xmm6
+ pxor xmm9, xmm7
+ movdqa xmm10, xmm0
+ punpcklqdq xmm10, xmm6
+ movdqa xmm11, xmm0
+ punpckhqdq xmm11, xmm6
+ movdqa xmm12, xmm10
+ pxor xmm12, xmm11
+ movdqa xmm10, xmm0
+ db $66, $44, $0F, $3A, $44, $D6, $00 // pclmulqdq xmm10, xmm6, 0
+ movdqa xmm11, xmm0
+ db $66, $44, $0F, $3A, $44, $DE, $11 // pclmulqdq xmm11, xmm6, 17
+ movdqa xmm0, xmm12
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm6, xmm10
+ pxor xmm6, xmm11
+ movdqa xmm12, xmm6
+ pxor xmm12, xmm0
+ movdqa xmm0, xmm12
+ pslldq xmm0, 8
+ movdqa xmm6, xmm10
+ pxor xmm6, xmm0
+ movdqa xmm0, xmm12
+ psrldq xmm0, 8
+ movdqa xmm10, xmm11
+ pxor xmm10, xmm0
+ movdqa xmm0, xmm3
+ punpcklqdq xmm0, xmm7
+ movdqa xmm11, xmm3
+ punpckhqdq xmm11, xmm7
+ movdqa xmm12, xmm0
+ pxor xmm12, xmm11
+ movdqa xmm0, xmm3
+ db $66, $0F, $3A, $44, $C7, $00 // pclmulqdq xmm0, xmm7, 0
+ movdqa xmm11, xmm3
+ db $66, $44, $0F, $3A, $44, $DF, $11 // pclmulqdq xmm11, xmm7, 17
+ movdqa xmm3, xmm12
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm7, xmm0
+ pxor xmm7, xmm11
+ movdqa xmm12, xmm7
+ pxor xmm12, xmm3
+ movdqa xmm3, xmm12
+ pslldq xmm3, 8
+ movdqa xmm7, xmm0
+ pxor xmm7, xmm3
+ movdqa xmm0, xmm12
+ psrldq xmm0, 8
+ movdqa xmm3, xmm11
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm8
+ punpcklqdq xmm0, xmm9
+ movdqa xmm11, xmm8
+ punpckhqdq xmm11, xmm9
+ movdqa xmm12, xmm0
+ pxor xmm12, xmm11
+ movdqa xmm0, xmm8
+ db $66, $41, $0F, $3A, $44, $C1, $00 // pclmulqdq xmm0, xmm9, 0
+ movdqa xmm11, xmm8
+ db $66, $45, $0F, $3A, $44, $D9, $11 // pclmulqdq xmm11, xmm9, 17
+ movdqa xmm8, xmm12
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm11
+ movdqa xmm12, xmm9
+ pxor xmm12, xmm8
+ movdqa xmm8, xmm12
+ pslldq xmm8, 8
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm8
+ movdqa xmm0, xmm12
+ psrldq xmm0, 8
+ movdqa xmm8, xmm11
+ pxor xmm8, xmm0
+ movdqa xmm0, xmm10
+ pxor xmm0, xmm7
+ movdqa xmm7, xmm9
+ pxor xmm7, xmm6
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm7
+ movdqa xmm7, xmm8
+ pxor xmm7, xmm3
+ movdqa xmm8, xmm0
+ pxor xmm8, xmm7
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [rdx + 8]
+ punpcklqdq xmm0, xmm15
+ movq xmm7, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [rdx + 40]
+ punpcklqdq xmm7, xmm15
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm7
+ movq xmm0, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [rdx + 24]
+ punpcklqdq xmm0, xmm15
+ movq xmm7, qword ptr [rdx + 48]
+ movq xmm15, qword ptr [rdx + 56]
+ punpcklqdq xmm7, xmm15
+ movdqa xmm11, xmm0
+ pxor xmm11, xmm7
+ movq xmm0, qword ptr [r8 + 0]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm0, xmm15
+ movq xmm7, qword ptr [r8 + 32]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm7, xmm15
+ movdqa xmm12, xmm0
+ pxor xmm12, xmm7
+ movq xmm0, qword ptr [r8 + 16]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm0, xmm15
+ movq xmm7, qword ptr [r8 + 48]
+ movq xmm15, qword ptr [r8 + 56]
+ punpcklqdq xmm7, xmm15
+ movdqa xmm13, xmm0
+ pxor xmm13, xmm7
+ movdqa xmm0, xmm10
+ pxor xmm0, xmm11
+ movdqa xmm7, xmm12
+ pxor xmm7, xmm13
+ movdqa xmm14, xmm10
+ punpcklqdq xmm14, xmm12
+ movdqu [rsp + 0], xmm3
+ movdqa xmm3, xmm10
+ punpckhqdq xmm3, xmm12
+ movdqu [rsp + 16], xmm8
+ movdqa xmm8, xmm14
+ pxor xmm8, xmm3
+ movdqa xmm3, xmm10
+ db $66, $41, $0F, $3A, $44, $DC, $00 // pclmulqdq xmm3, xmm12, 0
+ movdqa xmm14, xmm10
+ db $66, $45, $0F, $3A, $44, $F4, $11 // pclmulqdq xmm14, xmm12, 17
+ movdqa xmm10, xmm8
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm14
+ movdqa xmm12, xmm8
+ pxor xmm12, xmm10
+ movdqa xmm8, xmm12
+ pslldq xmm8, 8
+ movdqa xmm10, xmm3
+ pxor xmm10, xmm8
+ movdqa xmm3, xmm12
+ psrldq xmm3, 8
+ movdqa xmm8, xmm14
+ pxor xmm8, xmm3
+ movdqa xmm3, xmm11
+ punpcklqdq xmm3, xmm13
+ movdqa xmm12, xmm11
+ punpckhqdq xmm12, xmm13
+ movdqa xmm14, xmm3
+ pxor xmm14, xmm12
+ movdqa xmm3, xmm11
+ db $66, $41, $0F, $3A, $44, $DD, $00 // pclmulqdq xmm3, xmm13, 0
+ movdqa xmm12, xmm11
+ db $66, $45, $0F, $3A, $44, $E5, $11 // pclmulqdq xmm12, xmm13, 17
+ movdqa xmm11, xmm14
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm13, xmm3
+ pxor xmm13, xmm12
+ movdqa xmm14, xmm13
+ pxor xmm14, xmm11
+ movdqa xmm11, xmm14
+ pslldq xmm11, 8
+ movdqa xmm13, xmm3
+ pxor xmm13, xmm11
+ movdqa xmm3, xmm14
+ psrldq xmm3, 8
+ movdqa xmm11, xmm12
+ pxor xmm11, xmm3
+ movdqa xmm3, xmm0
+ punpcklqdq xmm3, xmm7
+ movdqa xmm12, xmm0
+ punpckhqdq xmm12, xmm7
+ movdqa xmm14, xmm3
+ pxor xmm14, xmm12
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DF, $00 // pclmulqdq xmm3, xmm7, 0
+ movdqa xmm12, xmm0
+ db $66, $44, $0F, $3A, $44, $E7, $11 // pclmulqdq xmm12, xmm7, 17
+ movdqa xmm0, xmm14
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm7, xmm3
+ pxor xmm7, xmm12
+ movdqa xmm14, xmm7
+ pxor xmm14, xmm0
+ movdqa xmm0, xmm14
+ pslldq xmm0, 8
+ movdqa xmm7, xmm3
+ pxor xmm7, xmm0
+ movdqa xmm0, xmm14
+ psrldq xmm0, 8
+ movdqa xmm3, xmm12
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm8
+ pxor xmm0, xmm13
+ movdqa xmm8, xmm7
+ pxor xmm8, xmm10
+ movdqa xmm7, xmm0
+ pxor xmm7, xmm8
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm11
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm8
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm6
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm9
+ movdqa xmm1, xmm10
+ pxor xmm1, xmm2
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm5
+ movdqa xmm7, xmm4
+ pxor xmm7, xmm1
+ movdqu xmm1, [rsp + 16]
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm8
+ movdqu xmm0, [rsp + 0]
+ movdqa xmm8, xmm11
+ pxor xmm8, xmm0
+ movdqa xmm9, xmm4
+ pxor xmm9, xmm8
+ movdqu [r9 + 0], xmm2
+ movdqu [r9 + 16], xmm5
+ movdqu [r9 + 32], xmm6
+ movdqu [r9 + 48], xmm7
+ movdqu [r9 + 64], xmm3
+ movdqu [r9 + 80], xmm9
+ movdqu [r9 + 96], xmm1
+ movdqu [r9 + 112], xmm0
+ add rsp, 32
+ ret
+
+@@BinPolySmallSize9:
+ sub rsp, 192
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [r8 + 0]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 8]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [r8 + 16]
+ punpcklqdq xmm2, xmm15
+ movq xmm3, qword ptr [rdx + 24]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movq xmm4, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [r8 + 32]
+ punpcklqdq xmm4, xmm15
+ movq xmm5, qword ptr [rdx + 40]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm5, xmm15
+ movq xmm6, qword ptr [rdx + 48]
+ movq xmm15, qword ptr [r8 + 48]
+ punpcklqdq xmm6, xmm15
+ movq xmm7, qword ptr [rdx + 56]
+ movq xmm15, qword ptr [r8 + 56]
+ punpcklqdq xmm7, xmm15
+ movq xmm8, qword ptr [rdx + 64]
+ movq xmm15, qword ptr [r8 + 64]
+ punpcklqdq xmm8, xmm15
+ movdqa xmm9, xmm0
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm1
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm2
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm0
+ pxor xmm12, xmm1
+ movdqa xmm13, xmm0
+ pxor xmm13, xmm2
+ movdqa xmm14, xmm1
+ pxor xmm14, xmm2
+ movdqu [rsp + 0], xmm5
+ movdqa xmm5, xmm12
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm12, xmm13
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm13, xmm14
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm14, xmm5
+ pxor xmm14, xmm9
+ movdqa xmm5, xmm14
+ pxor xmm5, xmm10
+ movdqa xmm14, xmm12
+ pxor xmm14, xmm9
+ movdqa xmm12, xmm14
+ pxor xmm12, xmm11
+ movdqa xmm14, xmm13
+ pxor xmm14, xmm10
+ movdqa xmm13, xmm14
+ pxor xmm13, xmm11
+ movdqa xmm14, xmm5
+ pslldq xmm14, 8
+ movdqu [rsp + 16], xmm8
+ movdqa xmm8, xmm9
+ pxor xmm8, xmm14
+ movdqa xmm9, xmm5
+ psrldq xmm9, 8
+ movdqa xmm5, xmm10
+ pxor xmm5, xmm9
+ movdqa xmm9, xmm13
+ pslldq xmm9, 8
+ movdqa xmm10, xmm12
+ pxor xmm10, xmm9
+ movdqa xmm9, xmm5
+ pxor xmm9, xmm10
+ movdqa xmm5, xmm13
+ psrldq xmm5, 8
+ movdqa xmm10, xmm11
+ pxor xmm10, xmm5
+ movdqa xmm5, xmm3
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm11, xmm4
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqu xmm12, [rsp + 0]
+ movdqa xmm13, xmm12
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm14, xmm3
+ pxor xmm14, xmm4
+ movdqu [rsp + 32], xmm8
+ movdqa xmm8, xmm3
+ pxor xmm8, xmm12
+ movdqu [rsp + 48], xmm10
+ movdqa xmm10, xmm4
+ pxor xmm10, xmm12
+ movdqu [rsp + 64], xmm9
+ movdqa xmm9, xmm14
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm14, xmm8
+ db $66, $45, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm14, xmm14, 1
+ movdqa xmm8, xmm10
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm10, xmm9
+ pxor xmm10, xmm5
+ movdqa xmm9, xmm10
+ pxor xmm9, xmm11
+ movdqa xmm10, xmm14
+ pxor xmm10, xmm5
+ movdqa xmm14, xmm10
+ pxor xmm14, xmm13
+ movdqa xmm10, xmm8
+ pxor xmm10, xmm11
+ movdqa xmm8, xmm10
+ pxor xmm8, xmm13
+ movdqa xmm10, xmm9
+ pslldq xmm10, 8
+ movdqu [rsp + 0], xmm12
+ movdqa xmm12, xmm5
+ pxor xmm12, xmm10
+ movdqa xmm5, xmm9
+ psrldq xmm5, 8
+ movdqa xmm9, xmm11
+ pxor xmm9, xmm5
+ movdqa xmm5, xmm8
+ pslldq xmm5, 8
+ movdqa xmm10, xmm14
+ pxor xmm10, xmm5
+ movdqa xmm5, xmm9
+ pxor xmm5, xmm10
+ movdqa xmm9, xmm8
+ psrldq xmm9, 8
+ movdqa xmm8, xmm13
+ pxor xmm8, xmm9
+ movdqa xmm9, xmm6
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm7
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqu xmm11, [rsp + 16]
+ movdqa xmm13, xmm11
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm14, xmm6
+ pxor xmm14, xmm7
+ movdqu [rsp + 80], xmm8
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm11
+ movdqu [rsp + 96], xmm5
+ movdqa xmm5, xmm7
+ pxor xmm5, xmm11
+ movdqu [rsp + 112], xmm12
+ movdqa xmm12, xmm14
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm14, xmm8
+ db $66, $45, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm14, xmm14, 1
+ movdqa xmm8, xmm5
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm5, xmm12
+ pxor xmm5, xmm9
+ movdqa xmm12, xmm5
+ pxor xmm12, xmm10
+ movdqa xmm5, xmm14
+ pxor xmm5, xmm9
+ movdqa xmm14, xmm5
+ pxor xmm14, xmm13
+ movdqa xmm5, xmm8
+ pxor xmm5, xmm10
+ movdqa xmm8, xmm5
+ pxor xmm8, xmm13
+ movdqa xmm5, xmm12
+ pslldq xmm5, 8
+ movdqu [rsp + 16], xmm11
+ movdqa xmm11, xmm9
+ pxor xmm11, xmm5
+ movdqa xmm5, xmm12
+ psrldq xmm5, 8
+ movdqa xmm9, xmm10
+ pxor xmm9, xmm5
+ movdqa xmm5, xmm8
+ pslldq xmm5, 8
+ movdqa xmm10, xmm14
+ pxor xmm10, xmm5
+ movdqa xmm5, xmm9
+ pxor xmm5, xmm10
+ movdqa xmm9, xmm8
+ psrldq xmm9, 8
+ movdqa xmm8, xmm13
+ pxor xmm8, xmm9
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm3
+ movdqa xmm10, xmm1
+ pxor xmm10, xmm4
+ movdqu xmm12, [rsp + 0]
+ movdqa xmm13, xmm2
+ pxor xmm13, xmm12
+ movdqa xmm14, xmm9
+ db $66, $45, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm14, xmm14, 1
+ movdqu [rsp + 128], xmm8
+ movdqa xmm8, xmm10
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqu [rsp + 144], xmm5
+ movdqa xmm5, xmm13
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqu [rsp + 160], xmm11
+ movdqa xmm11, xmm9
+ pxor xmm11, xmm10
+ movdqu [rsp + 0], xmm12
+ movdqa xmm12, xmm9
+ pxor xmm12, xmm13
+ movdqa xmm9, xmm10
+ pxor xmm9, xmm13
+ movdqa xmm10, xmm11
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm12
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm9
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm9, xmm10
+ pxor xmm9, xmm14
+ movdqa xmm10, xmm9
+ pxor xmm10, xmm8
+ movdqa xmm9, xmm11
+ pxor xmm9, xmm14
+ movdqa xmm11, xmm9
+ pxor xmm11, xmm5
+ movdqa xmm9, xmm12
+ pxor xmm9, xmm8
+ movdqa xmm12, xmm9
+ pxor xmm12, xmm5
+ movdqa xmm9, xmm10
+ pslldq xmm9, 8
+ movdqa xmm13, xmm14
+ pxor xmm13, xmm9
+ movdqa xmm9, xmm10
+ psrldq xmm9, 8
+ movdqa xmm10, xmm8
+ pxor xmm10, xmm9
+ movdqa xmm8, xmm12
+ pslldq xmm8, 8
+ movdqa xmm9, xmm11
+ pxor xmm9, xmm8
+ movdqa xmm8, xmm10
+ pxor xmm8, xmm9
+ movdqa xmm9, xmm12
+ psrldq xmm9, 8
+ movdqa xmm10, xmm5
+ pxor xmm10, xmm9
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm7
+ movdqu xmm1, [rsp + 16]
+ movdqa xmm9, xmm2
+ pxor xmm9, xmm1
+ movdqa xmm2, xmm5
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm11, xmm0
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm9
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm14, xmm5
+ pxor xmm14, xmm0
+ movdqu [rsp + 176], xmm10
+ movdqa xmm10, xmm5
+ pxor xmm10, xmm9
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm9
+ movdqa xmm0, xmm14
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm9, xmm10
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm5
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm2
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm11
+ movdqa xmm5, xmm9
+ pxor xmm5, xmm2
+ movdqa xmm9, xmm5
+ pxor xmm9, xmm12
+ movdqa xmm5, xmm10
+ pxor xmm5, xmm11
+ movdqa xmm10, xmm5
+ pxor xmm10, xmm12
+ movdqa xmm5, xmm0
+ pslldq xmm5, 8
+ movdqa xmm14, xmm2
+ pxor xmm14, xmm5
+ movdqa xmm2, xmm0
+ psrldq xmm2, 8
+ movdqa xmm0, xmm11
+ pxor xmm0, xmm2
+ movdqa xmm2, xmm10
+ pslldq xmm2, 8
+ movdqa xmm5, xmm9
+ pxor xmm5, xmm2
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm5
+ movdqa xmm0, xmm10
+ psrldq xmm0, 8
+ movdqa xmm5, xmm12
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm6
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm7
+ movdqu xmm4, [rsp + 0]
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm4, xmm3
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm7, xmm6
+ db $66, $0F, $3A, $44, $FF, $01 // pclmulqdq xmm7, xmm7, 1
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm3
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm6
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm6
+ movdqa xmm3, xmm9
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm6, xmm10
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm9, xmm0
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm1
+ movdqa xmm3, xmm0
+ pxor xmm3, xmm4
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm1
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm7
+ movdqa xmm0, xmm9
+ pxor xmm0, xmm4
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm7
+ movdqa xmm0, xmm3
+ pslldq xmm0, 8
+ movdqa xmm10, xmm1
+ pxor xmm10, xmm0
+ movdqa xmm0, xmm3
+ psrldq xmm0, 8
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm0
+ movdqa xmm0, xmm9
+ pslldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm9
+ psrldq xmm1, 8
+ movdqa xmm3, xmm7
+ pxor xmm3, xmm1
+ movdqu xmm1, [rsp + 32]
+ movdqa xmm4, xmm13
+ pxor xmm4, xmm1
+ movdqu xmm6, [rsp + 112]
+ movdqa xmm7, xmm4
+ pxor xmm7, xmm6
+ movdqu xmm4, [rsp + 64]
+ movdqa xmm9, xmm8
+ pxor xmm9, xmm4
+ movdqu xmm8, [rsp + 96]
+ movdqa xmm11, xmm9
+ pxor xmm11, xmm8
+ movdqu xmm9, [rsp + 176]
+ movdqu xmm12, [rsp + 48]
+ movdqa xmm13, xmm9
+ pxor xmm13, xmm12
+ movdqu xmm9, [rsp + 80]
+ movdqu [rsp + 32], xmm1
+ movdqa xmm1, xmm13
+ pxor xmm1, xmm9
+ movdqu xmm13, [rsp + 32]
+ movdqu [rsp + 80], xmm9
+ movdqa xmm9, xmm14
+ pxor xmm9, xmm13
+ movdqu xmm14, [rsp + 160]
+ movdqu [rsp + 32], xmm13
+ movdqa xmm13, xmm9
+ pxor xmm13, xmm14
+ movdqa xmm9, xmm2
+ pxor xmm9, xmm4
+ movdqu xmm2, [rsp + 144]
+ movdqu [rsp + 160], xmm14
+ movdqa xmm14, xmm9
+ pxor xmm14, xmm2
+ movdqa xmm9, xmm5
+ pxor xmm9, xmm12
+ movdqu xmm5, [rsp + 128]
+ movdqu [rsp + 144], xmm2
+ movdqa xmm2, xmm9
+ pxor xmm2, xmm5
+ movdqa xmm9, xmm10
+ pxor xmm9, xmm6
+ movdqu xmm10, [rsp + 160]
+ movdqu [rsp + 128], xmm5
+ movdqa xmm5, xmm9
+ pxor xmm5, xmm10
+ movdqa xmm9, xmm0
+ pxor xmm9, xmm8
+ movdqu xmm0, [rsp + 144]
+ movdqu [rsp + 160], xmm10
+ movdqa xmm10, xmm9
+ pxor xmm10, xmm0
+ movdqu xmm9, [rsp + 80]
+ movdqu [rsp + 144], xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm9
+ movdqu xmm3, [rsp + 128]
+ movdqu [rsp + 176], xmm10
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm3
+ movdqa xmm0, xmm7
+ pslldq xmm0, 8
+ movdqu [rsp + 128], xmm3
+ movdqa xmm3, xmm4
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm7
+ psrldq xmm0, 8
+ movdqa xmm4, xmm12
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm11
+ pslldq xmm0, 8
+ movdqa xmm7, xmm4
+ pxor xmm7, xmm0
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm13
+ movdqa xmm4, xmm11
+ psrldq xmm4, 8
+ movdqa xmm6, xmm1
+ pslldq xmm6, 8
+ movdqa xmm11, xmm4
+ pxor xmm11, xmm6
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm11
+ movdqa xmm0, xmm8
+ pxor xmm0, xmm14
+ movdqa xmm6, xmm1
+ psrldq xmm6, 8
+ movdqa xmm1, xmm5
+ pslldq xmm1, 8
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm8
+ movdqa xmm0, xmm9
+ pxor xmm0, xmm2
+ movdqa xmm2, xmm5
+ psrldq xmm2, 8
+ movdqu xmm5, [rsp + 176]
+ movdqa xmm6, xmm5
+ pslldq xmm6, 8
+ movdqa xmm8, xmm2
+ pxor xmm8, xmm6
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm8
+ movdqa xmm0, xmm5
+ psrldq xmm0, 8
+ movdqa xmm5, xmm10
+ pslldq xmm5, 8
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm5
+ movdqu xmm0, [rsp + 160]
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqa xmm0, xmm10
+ psrldq xmm0, 8
+ movdqu xmm6, [rsp + 144]
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm0
+ movdqu xmm0, [rsp + 32]
+ movdqu [r9 + 0], xmm0
+ movdqu [r9 + 16], xmm3
+ movdqu [r9 + 32], xmm7
+ movdqu [r9 + 48], xmm4
+ movdqu [r9 + 64], xmm1
+ movdqu [r9 + 80], xmm2
+ movdqu [r9 + 96], xmm5
+ movdqu [r9 + 112], xmm8
+ movdqu xmm0, [rsp + 128]
+ movdqu [r9 + 128], xmm0
+ add rsp, 192
+ ret
+
+@@BinPolySmallSize10:
+ sub rsp, 288
+ movq xmm0, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [r8 + 0]
+ punpcklqdq xmm0, xmm15
+ movq xmm1, qword ptr [rdx + 8]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm1, xmm15
+ movq xmm2, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [r8 + 16]
+ punpcklqdq xmm2, xmm15
+ movq xmm3, qword ptr [rdx + 24]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm3, xmm15
+ movq xmm4, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [r8 + 32]
+ punpcklqdq xmm4, xmm15
+ movdqa xmm5, xmm0
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm6, xmm1
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm7, xmm2
+ db $66, $0F, $3A, $44, $FF, $01 // pclmulqdq xmm7, xmm7, 1
+ movdqa xmm8, xmm3
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm9, xmm4
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm1
+ movdqa xmm11, xmm0
+ pxor xmm11, xmm2
+ movdqa xmm12, xmm0
+ pxor xmm12, xmm3
+ movdqa xmm13, xmm0
+ pxor xmm13, xmm4
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm2
+ movdqa xmm14, xmm1
+ pxor xmm14, xmm3
+ movdqu [rsp + 0], xmm9
+ movdqa xmm9, xmm1
+ pxor xmm9, xmm4
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm3
+ movdqu [rsp + 16], xmm8
+ movdqa xmm8, xmm2
+ pxor xmm8, xmm4
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm4
+ movdqa xmm3, xmm10
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm4, xmm11
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm10, xmm12
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm13
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm0
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm0, xmm14
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm13, xmm9
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm9, xmm1
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm1, xmm8
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm8, xmm2
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm2, xmm3
+ pxor xmm2, xmm5
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm6
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm5
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm7
+ movdqa xmm2, xmm10
+ pxor xmm2, xmm5
+ movdqu xmm10, [rsp + 16]
+ movdqa xmm14, xmm2
+ pxor xmm14, xmm10
+ movdqa xmm2, xmm11
+ pxor xmm2, xmm5
+ movdqu xmm11, [rsp + 0]
+ movdqu [rsp + 16], xmm10
+ movdqa xmm10, xmm2
+ pxor xmm10, xmm11
+ movdqa xmm2, xmm12
+ pxor xmm2, xmm6
+ movdqa xmm12, xmm2
+ pxor xmm12, xmm7
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm6
+ movdqu xmm0, [rsp + 16]
+ movdqu [rsp + 0], xmm11
+ movdqa xmm11, xmm2
+ pxor xmm11, xmm0
+ movdqa xmm2, xmm13
+ pxor xmm2, xmm6
+ movdqu xmm13, [rsp + 0]
+ movdqu [rsp + 16], xmm0
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm13
+ movdqa xmm2, xmm9
+ pxor xmm2, xmm7
+ movdqu xmm9, [rsp + 16]
+ movdqu [rsp + 0], xmm13
+ movdqa xmm13, xmm2
+ pxor xmm13, xmm9
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm7
+ movdqu xmm1, [rsp + 0]
+ movdqu [rsp + 16], xmm9
+ movdqa xmm9, xmm2
+ pxor xmm9, xmm1
+ movdqu xmm2, [rsp + 16]
+ movdqu [rsp + 0], xmm1
+ movdqa xmm1, xmm8
+ pxor xmm1, xmm2
+ movdqu xmm8, [rsp + 0]
+ movdqu [rsp + 32], xmm9
+ movdqa xmm9, xmm1
+ pxor xmm9, xmm8
+ movdqa xmm1, xmm14
+ pxor xmm1, xmm12
+ movdqa xmm12, xmm10
+ pxor xmm12, xmm11
+ movdqa xmm10, xmm0
+ pxor xmm10, xmm13
+ movdqa xmm0, xmm3
+ pslldq xmm0, 8
+ movdqa xmm11, xmm5
+ pxor xmm11, xmm0
+ movdqa xmm0, xmm3
+ psrldq xmm0, 8
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm1
+ pslldq xmm0, 8
+ movdqa xmm5, xmm4
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm3
+ pxor xmm0, xmm5
+ movdqa xmm3, xmm1
+ psrldq xmm3, 8
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm3
+ movdqa xmm3, xmm10
+ pslldq xmm3, 8
+ movdqa xmm4, xmm12
+ pxor xmm4, xmm3
+ movdqa xmm3, xmm1
+ pxor xmm3, xmm4
+ movdqa xmm1, xmm10
+ psrldq xmm1, 8
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm1
+ movdqa xmm1, xmm9
+ pslldq xmm1, 8
+ movdqu xmm2, [rsp + 32]
+ movdqa xmm5, xmm2
+ pxor xmm5, xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm5
+ movdqa xmm2, xmm9
+ psrldq xmm2, 8
+ movdqa xmm4, xmm8
+ pxor xmm4, xmm2
+ movq xmm2, qword ptr [rdx + 40]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm2, xmm15
+ movq xmm5, qword ptr [rdx + 48]
+ movq xmm15, qword ptr [r8 + 48]
+ punpcklqdq xmm5, xmm15
+ movq xmm6, qword ptr [rdx + 56]
+ movq xmm15, qword ptr [r8 + 56]
+ punpcklqdq xmm6, xmm15
+ movq xmm7, qword ptr [rdx + 64]
+ movq xmm15, qword ptr [r8 + 64]
+ punpcklqdq xmm7, xmm15
+ movq xmm8, qword ptr [rdx + 72]
+ movq xmm15, qword ptr [r8 + 72]
+ punpcklqdq xmm8, xmm15
+ movdqa xmm9, xmm2
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm10, xmm5
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm12, xmm6
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm13, xmm7
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm14, xmm8
+ db $66, $45, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm14, xmm14, 1
+ movdqu [rsp + 0], xmm4
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm5
+ movdqu [rsp + 32], xmm1
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm6
+ movdqu [rsp + 16], xmm3
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm7
+ movdqu [rsp + 48], xmm0
+ movdqa xmm0, xmm2
+ pxor xmm0, xmm8
+ movdqa xmm2, xmm5
+ pxor xmm2, xmm6
+ movdqu [rsp + 64], xmm11
+ movdqa xmm11, xmm5
+ pxor xmm11, xmm7
+ movdqu [rsp + 80], xmm14
+ movdqa xmm14, xmm5
+ pxor xmm14, xmm8
+ movdqa xmm5, xmm6
+ pxor xmm5, xmm7
+ movdqu [rsp + 96], xmm13
+ movdqa xmm13, xmm6
+ pxor xmm13, xmm8
+ movdqa xmm6, xmm7
+ pxor xmm6, xmm8
+ movdqa xmm7, xmm4
+ db $66, $0F, $3A, $44, $FF, $01 // pclmulqdq xmm7, xmm7, 1
+ movdqa xmm4, xmm1
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm1, xmm3
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm0
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm0, xmm2
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm11
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm8, xmm14
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm11, xmm5
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm5, xmm13
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm13, xmm6
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm6, xmm7
+ pxor xmm6, xmm9
+ movdqa xmm7, xmm6
+ pxor xmm7, xmm10
+ movdqa xmm6, xmm4
+ pxor xmm6, xmm9
+ movdqa xmm4, xmm6
+ pxor xmm4, xmm12
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm9
+ movdqu xmm1, [rsp + 96]
+ movdqa xmm14, xmm6
+ pxor xmm14, xmm1
+ movdqa xmm6, xmm3
+ pxor xmm6, xmm9
+ movdqu xmm3, [rsp + 80]
+ movdqu [rsp + 96], xmm1
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm3
+ movdqa xmm6, xmm0
+ pxor xmm6, xmm10
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm12
+ movdqa xmm6, xmm2
+ pxor xmm6, xmm10
+ movdqu xmm2, [rsp + 96]
+ movdqu [rsp + 80], xmm3
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm2
+ movdqa xmm6, xmm8
+ pxor xmm6, xmm10
+ movdqu xmm8, [rsp + 80]
+ movdqu [rsp + 96], xmm2
+ movdqa xmm2, xmm6
+ pxor xmm2, xmm8
+ movdqa xmm6, xmm11
+ pxor xmm6, xmm12
+ movdqu xmm11, [rsp + 96]
+ movdqu [rsp + 80], xmm8
+ movdqa xmm8, xmm6
+ pxor xmm8, xmm11
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm12
+ movdqu xmm5, [rsp + 80]
+ movdqu [rsp + 96], xmm11
+ movdqa xmm11, xmm6
+ pxor xmm11, xmm5
+ movdqu xmm6, [rsp + 96]
+ movdqu [rsp + 80], xmm5
+ movdqa xmm5, xmm13
+ pxor xmm5, xmm6
+ movdqu xmm13, [rsp + 80]
+ movdqu [rsp + 112], xmm11
+ movdqa xmm11, xmm5
+ pxor xmm11, xmm13
+ movdqa xmm5, xmm14
+ pxor xmm5, xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm2
+ pxor xmm1, xmm8
+ movdqa xmm2, xmm7
+ pslldq xmm2, 8
+ movdqa xmm3, xmm9
+ pxor xmm3, xmm2
+ movdqa xmm2, xmm7
+ psrldq xmm2, 8
+ movdqa xmm7, xmm10
+ pxor xmm7, xmm2
+ movdqa xmm2, xmm5
+ pslldq xmm2, 8
+ movdqa xmm8, xmm4
+ pxor xmm8, xmm2
+ movdqa xmm2, xmm7
+ pxor xmm2, xmm8
+ movdqa xmm4, xmm5
+ psrldq xmm4, 8
+ movdqa xmm5, xmm12
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm1
+ pslldq xmm4, 8
+ movdqa xmm7, xmm0
+ pxor xmm7, xmm4
+ movdqa xmm0, xmm5
+ pxor xmm0, xmm7
+ movdqa xmm4, xmm1
+ psrldq xmm4, 8
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm4
+ movdqa xmm4, xmm11
+ pslldq xmm4, 8
+ movdqu xmm5, [rsp + 112]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm6
+ movdqa xmm1, xmm11
+ psrldq xmm1, 8
+ movdqa xmm5, xmm13
+ pxor xmm5, xmm1
+ movq xmm1, qword ptr [rdx + 0]
+ movq xmm15, qword ptr [r8 + 40]
+ punpcklqdq xmm1, xmm15
+ movq xmm6, qword ptr [rdx + 8]
+ movq xmm15, qword ptr [r8 + 48]
+ punpcklqdq xmm6, xmm15
+ movq xmm7, qword ptr [rdx + 16]
+ movq xmm15, qword ptr [r8 + 56]
+ punpcklqdq xmm7, xmm15
+ movq xmm8, qword ptr [rdx + 24]
+ movq xmm15, qword ptr [r8 + 64]
+ punpcklqdq xmm8, xmm15
+ movq xmm9, qword ptr [rdx + 32]
+ movq xmm15, qword ptr [r8 + 72]
+ punpcklqdq xmm9, xmm15
+ movdqa xmm10, xmm1
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm6
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm7
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm13, xmm8
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm14, xmm9
+ db $66, $45, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm14, xmm14, 1
+ movdqu [rsp + 80], xmm5
+ movdqa xmm5, xmm1
+ pxor xmm5, xmm6
+ movdqu [rsp + 112], xmm4
+ movdqa xmm4, xmm1
+ pxor xmm4, xmm7
+ movdqu [rsp + 96], xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm8
+ movdqu [rsp + 128], xmm2
+ movdqa xmm2, xmm1
+ pxor xmm2, xmm9
+ movdqa xmm1, xmm6
+ pxor xmm1, xmm7
+ movdqu [rsp + 144], xmm3
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm8
+ movdqu [rsp + 160], xmm14
+ movdqa xmm14, xmm6
+ pxor xmm14, xmm9
+ movdqa xmm6, xmm7
+ pxor xmm6, xmm8
+ movdqu [rsp + 176], xmm13
+ movdqa xmm13, xmm7
+ pxor xmm13, xmm9
+ movdqa xmm7, xmm8
+ pxor xmm7, xmm9
+ movdqa xmm8, xmm5
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm5, xmm4
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm4, xmm0
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm0, xmm2
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm2, xmm1
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm1, xmm3
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm3, xmm14
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm9, xmm6
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm6, xmm13
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm13, xmm7
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm7, xmm8
+ pxor xmm7, xmm10
+ movdqa xmm8, xmm7
+ pxor xmm8, xmm11
+ movdqa xmm7, xmm5
+ pxor xmm7, xmm10
+ movdqa xmm5, xmm7
+ pxor xmm5, xmm12
+ movdqa xmm7, xmm4
+ pxor xmm7, xmm10
+ movdqu xmm4, [rsp + 176]
+ movdqa xmm14, xmm7
+ pxor xmm14, xmm4
+ movdqa xmm7, xmm0
+ pxor xmm7, xmm10
+ movdqu xmm0, [rsp + 160]
+ movdqu [rsp + 176], xmm4
+ movdqa xmm4, xmm7
+ pxor xmm4, xmm0
+ movdqa xmm7, xmm2
+ pxor xmm7, xmm11
+ movdqa xmm2, xmm7
+ pxor xmm2, xmm12
+ movdqa xmm7, xmm1
+ pxor xmm7, xmm11
+ movdqu xmm1, [rsp + 176]
+ movdqu [rsp + 160], xmm0
+ movdqa xmm0, xmm7
+ pxor xmm0, xmm1
+ movdqa xmm7, xmm3
+ pxor xmm7, xmm11
+ movdqu xmm3, [rsp + 160]
+ movdqu [rsp + 176], xmm1
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm3
+ movdqa xmm7, xmm9
+ pxor xmm7, xmm12
+ movdqu xmm9, [rsp + 176]
+ movdqu [rsp + 160], xmm3
+ movdqa xmm3, xmm7
+ pxor xmm3, xmm9
+ movdqa xmm7, xmm6
+ pxor xmm7, xmm12
+ movdqu xmm6, [rsp + 160]
+ movdqu [rsp + 176], xmm9
+ movdqa xmm9, xmm7
+ pxor xmm9, xmm6
+ movdqu xmm7, [rsp + 176]
+ movdqu [rsp + 160], xmm6
+ movdqa xmm6, xmm13
+ pxor xmm6, xmm7
+ movdqu xmm13, [rsp + 160]
+ movdqu [rsp + 192], xmm9
+ movdqa xmm9, xmm6
+ pxor xmm9, xmm13
+ movdqa xmm6, xmm14
+ pxor xmm6, xmm2
+ movdqa xmm2, xmm4
+ pxor xmm2, xmm0
+ movdqa xmm0, xmm1
+ pxor xmm0, xmm3
+ movdqa xmm1, xmm8
+ pslldq xmm1, 8
+ movdqa xmm3, xmm10
+ pxor xmm3, xmm1
+ movdqa xmm1, xmm8
+ psrldq xmm1, 8
+ movdqa xmm4, xmm11
+ pxor xmm4, xmm1
+ movdqa xmm1, xmm6
+ pslldq xmm1, 8
+ movdqa xmm8, xmm5
+ pxor xmm8, xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm8
+ movdqa xmm4, xmm6
+ psrldq xmm4, 8
+ movdqa xmm5, xmm12
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm0
+ pslldq xmm4, 8
+ movdqa xmm6, xmm2
+ pxor xmm6, xmm4
+ movdqa xmm2, xmm5
+ pxor xmm2, xmm6
+ movdqa xmm4, xmm0
+ psrldq xmm4, 8
+ movdqa xmm0, xmm7
+ pxor xmm0, xmm4
+ movdqa xmm4, xmm9
+ pslldq xmm4, 8
+ movdqu xmm5, [rsp + 192]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm6
+ movdqa xmm0, xmm9
+ psrldq xmm0, 8
+ movdqa xmm5, xmm13
+ pxor xmm5, xmm0
+ movq xmm0, qword ptr [rdx + 40]
+ movq xmm15, qword ptr [r8 + 0]
+ punpcklqdq xmm0, xmm15
+ movq xmm6, qword ptr [rdx + 48]
+ movq xmm15, qword ptr [r8 + 8]
+ punpcklqdq xmm6, xmm15
+ movq xmm7, qword ptr [rdx + 56]
+ movq xmm15, qword ptr [r8 + 16]
+ punpcklqdq xmm7, xmm15
+ movq xmm8, qword ptr [rdx + 64]
+ movq xmm15, qword ptr [r8 + 24]
+ punpcklqdq xmm8, xmm15
+ movq xmm9, qword ptr [rdx + 72]
+ movq xmm15, qword ptr [r8 + 32]
+ punpcklqdq xmm9, xmm15
+ movdqa xmm10, xmm0
+ db $66, $45, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm10, xmm10, 1
+ movdqa xmm11, xmm6
+ db $66, $45, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm11, xmm11, 1
+ movdqa xmm12, xmm7
+ db $66, $45, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm12, xmm12, 1
+ movdqa xmm13, xmm8
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm14, xmm9
+ db $66, $45, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm14, xmm14, 1
+ movdqu [rsp + 160], xmm5
+ movdqa xmm5, xmm0
+ pxor xmm5, xmm6
+ movdqu [rsp + 192], xmm4
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm7
+ movdqu [rsp + 176], xmm2
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm8
+ movdqu [rsp + 208], xmm1
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm9
+ movdqa xmm0, xmm6
+ pxor xmm0, xmm7
+ movdqu [rsp + 224], xmm3
+ movdqa xmm3, xmm6
+ pxor xmm3, xmm8
+ movdqu [rsp + 240], xmm14
+ movdqa xmm14, xmm6
+ pxor xmm14, xmm9
+ movdqa xmm6, xmm7
+ pxor xmm6, xmm8
+ movdqu [rsp + 256], xmm13
+ movdqa xmm13, xmm7
+ pxor xmm13, xmm9
+ movdqa xmm7, xmm8
+ pxor xmm7, xmm9
+ movdqa xmm8, xmm5
+ db $66, $45, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm8, xmm8, 1
+ movdqa xmm5, xmm4
+ db $66, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm5, xmm5, 1
+ movdqa xmm4, xmm2
+ db $66, $0F, $3A, $44, $E4, $01 // pclmulqdq xmm4, xmm4, 1
+ movdqa xmm2, xmm1
+ db $66, $0F, $3A, $44, $D2, $01 // pclmulqdq xmm2, xmm2, 1
+ movdqa xmm1, xmm0
+ db $66, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm1, xmm1, 1
+ movdqa xmm0, xmm3
+ db $66, $0F, $3A, $44, $C0, $01 // pclmulqdq xmm0, xmm0, 1
+ movdqa xmm3, xmm14
+ db $66, $0F, $3A, $44, $DB, $01 // pclmulqdq xmm3, xmm3, 1
+ movdqa xmm9, xmm6
+ db $66, $45, $0F, $3A, $44, $C9, $01 // pclmulqdq xmm9, xmm9, 1
+ movdqa xmm6, xmm13
+ db $66, $0F, $3A, $44, $F6, $01 // pclmulqdq xmm6, xmm6, 1
+ movdqa xmm13, xmm7
+ db $66, $45, $0F, $3A, $44, $ED, $01 // pclmulqdq xmm13, xmm13, 1
+ movdqa xmm7, xmm8
+ pxor xmm7, xmm10
+ movdqa xmm8, xmm7
+ pxor xmm8, xmm11
+ movdqa xmm7, xmm5
+ pxor xmm7, xmm10
+ movdqa xmm5, xmm7
+ pxor xmm5, xmm12
+ movdqa xmm7, xmm4
+ pxor xmm7, xmm10
+ movdqu xmm4, [rsp + 256]
+ movdqa xmm14, xmm7
+ pxor xmm14, xmm4
+ movdqa xmm7, xmm2
+ pxor xmm7, xmm10
+ movdqu xmm2, [rsp + 240]
+ movdqu [rsp + 256], xmm4
+ movdqa xmm4, xmm7
+ pxor xmm4, xmm2
+ movdqa xmm7, xmm1
+ pxor xmm7, xmm11
+ movdqa xmm1, xmm7
+ pxor xmm1, xmm12
+ movdqa xmm7, xmm0
+ pxor xmm7, xmm11
+ movdqu xmm0, [rsp + 256]
+ movdqu [rsp + 240], xmm2
+ movdqa xmm2, xmm7
+ pxor xmm2, xmm0
+ movdqa xmm7, xmm3
+ pxor xmm7, xmm11
+ movdqu xmm3, [rsp + 240]
+ movdqu [rsp + 256], xmm0
+ movdqa xmm0, xmm7
+ pxor xmm0, xmm3
+ movdqa xmm7, xmm9
+ pxor xmm7, xmm12
+ movdqu xmm9, [rsp + 256]
+ movdqu [rsp + 240], xmm3
+ movdqa xmm3, xmm7
+ pxor xmm3, xmm9
+ movdqa xmm7, xmm6
+ pxor xmm7, xmm12
+ movdqu xmm6, [rsp + 240]
+ movdqu [rsp + 256], xmm9
+ movdqa xmm9, xmm7
+ pxor xmm9, xmm6
+ movdqu xmm7, [rsp + 256]
+ movdqu [rsp + 240], xmm6
+ movdqa xmm6, xmm13
+ pxor xmm6, xmm7
+ movdqu xmm13, [rsp + 240]
+ movdqu [rsp + 272], xmm9
+ movdqa xmm9, xmm6
+ pxor xmm9, xmm13
+ movdqa xmm6, xmm14
+ pxor xmm6, xmm1
+ movdqa xmm1, xmm4
+ pxor xmm1, xmm2
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm3
+ movdqa xmm0, xmm8
+ pslldq xmm0, 8
+ movdqa xmm3, xmm10
+ pxor xmm3, xmm0
+ movdqa xmm0, xmm8
+ psrldq xmm0, 8
+ movdqa xmm4, xmm11
+ pxor xmm4, xmm0
+ movdqa xmm0, xmm6
+ pslldq xmm0, 8
+ movdqa xmm8, xmm5
+ pxor xmm8, xmm0
+ movdqa xmm0, xmm4
+ pxor xmm0, xmm8
+ movdqa xmm4, xmm6
+ psrldq xmm4, 8
+ movdqa xmm5, xmm12
+ pxor xmm5, xmm4
+ movdqa xmm4, xmm2
+ pslldq xmm4, 8
+ movdqa xmm6, xmm1
+ pxor xmm6, xmm4
+ movdqa xmm1, xmm5
+ pxor xmm1, xmm6
+ movdqa xmm4, xmm2
+ psrldq xmm4, 8
+ movdqa xmm2, xmm7
+ pxor xmm2, xmm4
+ movdqa xmm4, xmm9
+ pslldq xmm4, 8
+ movdqu xmm5, [rsp + 272]
+ movdqa xmm6, xmm5
+ pxor xmm6, xmm4
+ movdqa xmm4, xmm2
+ pxor xmm4, xmm6
+ movdqa xmm2, xmm9
+ psrldq xmm2, 8
+ movdqa xmm5, xmm13
+ pxor xmm5, xmm2
+ movdqu xmm2, [rsp + 224]
+ movdqa xmm6, xmm2
+ pxor xmm6, xmm3
+ movdqu xmm2, [rsp + 208]
+ movdqa xmm3, xmm2
+ pxor xmm3, xmm0
+ movdqu xmm0, [rsp + 176]
+ movdqa xmm2, xmm0
+ pxor xmm2, xmm1
+ movdqu xmm0, [rsp + 192]
+ movdqa xmm1, xmm0
+ pxor xmm1, xmm4
+ movdqu xmm0, [rsp + 160]
+ movdqa xmm4, xmm0
+ pxor xmm4, xmm5
+ movdqu xmm0, [rsp + 64]
+ movdqu [r9 + 0], xmm0
+ movdqu xmm0, [rsp + 48]
+ movdqu [r9 + 16], xmm0
+ movdqu xmm0, [rsp + 16]
+ movdqu [r9 + 32], xmm0
+ movdqu xmm0, [rsp + 32]
+ movdqu [r9 + 48], xmm0
+ movdqu xmm0, [rsp + 0]
+ movdqu [r9 + 64], xmm0
+ movdqu xmm0, [rsp + 144]
+ movdqu [r9 + 80], xmm0
+ movdqu xmm0, [rsp + 128]
+ movdqu [r9 + 96], xmm0
+ movdqu xmm0, [rsp + 96]
+ movdqu [r9 + 112], xmm0
+ movdqu xmm0, [rsp + 112]
+ movdqu [r9 + 128], xmm0
+ movdqu xmm0, [rsp + 80]
+ movdqu [r9 + 144], xmm0
+ movdqu xmm0, [r9 + 40]
+ pxor xmm0, xmm6
+ movdqu [r9 + 40], xmm0
+ movdqu xmm0, [r9 + 56]
+ pxor xmm0, xmm3
+ movdqu [r9 + 56], xmm0
+ movdqu xmm0, [r9 + 72]
+ pxor xmm0, xmm2
+ movdqu [r9 + 72], xmm0
+ movdqu xmm0, [r9 + 88]
+ pxor xmm0, xmm1
+ movdqu [r9 + 88], xmm0
+ movdqu xmm0, [r9 + 104]
+ pxor xmm0, xmm4
+ movdqu [r9 + 104], xmm0
+ add rsp, 288
+ ret
+
diff --git a/CryptoLib/src/Interfaces/Asn1/ClpIAsn1Objects.pas b/CryptoLib/src/Interfaces/Asn1/ClpIAsn1Objects.pas
index e3fa1eda..0243957e 100644
--- a/CryptoLib/src/Interfaces/Asn1/ClpIAsn1Objects.pas
+++ b/CryptoLib/src/Interfaces/Asn1/ClpIAsn1Objects.pas
@@ -651,6 +651,10 @@ interface
///
function ToAsn1External(): IDerExternal;
///
+ /// Convert to ASN.1 octet string.
+ ///
+ function ToAsn1OctetString(): IAsn1OctetString;
+ ///
/// Convert to ASN.1 set.
///
function ToAsn1Set(): IAsn1Set;
diff --git a/CryptoLib/src/Interfaces/Math/BinPoly/ClpIBinPolyInv.pas b/CryptoLib/src/Interfaces/Math/BinPoly/ClpIBinPolyInv.pas
new file mode 100644
index 00000000..9caf6933
--- /dev/null
+++ b/CryptoLib/src/Interfaces/Math/BinPoly/ClpIBinPolyInv.pas
@@ -0,0 +1,64 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIBinPolyInv;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes;
+
+type
+ ///
+ /// Multiplicative inversion in the field GF(2^n) = GF(2)[x] / f(x).
+ ///
+ ///
+ ///
+ /// Instances are produced by the static factories on TBinPolys.TBinPolysInv.
+ /// Inversion is only well-defined when the reduction polynomial backing the supplied
+ /// IBinPolyMul is irreducible, so that the quotient ring is a field. The binomial
+ /// reducer (x^n + 1) is always reducible (x = 1 is a root over GF(2)) and
+ /// must not be used. Irreducibility is the caller's attestation — it is not checked, and
+ /// a reducible polynomial yields a meaningless result (or stumbles on a non-invertible
+ /// element).
+ ///
+ ///
+ /// Polynomials use the same bit-packed TCryptoLibUInt64Array representation as
+ /// IBinPolyMul.
+ ///
+ ///
+ IBinPolyInv = interface(IInterface)
+ ['{C1D2E3F4-A5B6-4789-ABCD-EF0123456703}']
+ /// Polynomial bit-length n.
+ function GetN: Int32;
+ /// Number of UInt64 limbs required to hold a polynomial of length N.
+ function GetSize: Int32;
+ ///
+ /// Compute AZ = AX^{-1} mod f(x). By convention 0 maps to 0 — there is no
+ /// special case for it (nor for 1); both fall out of the computation, so the running cost
+ /// is independent of the element value. AX may alias AZ.
+ ///
+ procedure Invert(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+ property N: Int32 read GetN;
+ property Size: Int32 read GetSize;
+ end;
+
+implementation
+
+end.
diff --git a/CryptoLib/src/Interfaces/Math/BinPoly/ClpIBinPolyMul.pas b/CryptoLib/src/Interfaces/Math/BinPoly/ClpIBinPolyMul.pas
new file mode 100644
index 00000000..74e4ee21
--- /dev/null
+++ b/CryptoLib/src/Interfaces/Math/BinPoly/ClpIBinPolyMul.pas
@@ -0,0 +1,113 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIBinPolyMul;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes;
+
+type
+ ///
+ /// Reduction of an extended binary polynomial product into the quotient ring.
+ ///
+ ///
+ ///
+ /// Reduces the extended product in Att[AttOff..AttOff + 2*Size - 1] into
+ /// Az[AzOff..AzOff + Size - 1]. The reducer knows its own field size.
+ ///
+ ///
+ /// Post-condition on Att: arbitrary. The reducer may freely mutate any limb in
+ /// its window, and individual implementations are free not to write some limbs at all
+ /// (fully-unrolled and direct-to-Az variants do exactly this). Callers must
+ /// not read Att after Reduce returns, and if Att held
+ /// secret-bearing material they remain responsible for wiping it (see
+ /// TBinPolys.Clear).
+ ///
+ ///
+ IBinPolyReduce = interface(IInterface)
+ ['{C1D2E3F4-A5B6-4789-ABCD-EF0123456701}']
+ ///
+ /// Reduce an extended product buffer into a result buffer.
+ ///
+ /// Extended product buffer (2 * Size limbs).
+ /// Offset into .
+ /// Output buffer (Size limbs).
+ /// Offset into .
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+
+ ///
+ /// Binary polynomial arithmetic in GF(2)[x] / r(x), where r(x) is a binomial,
+ /// trinomial, or pentanomial.
+ ///
+ ///
+ ///
+ /// Instances are produced by the static factories on TBinPolys.TBinPolysMul.
+ /// Polynomials are stored bit-packed in TCryptoLibUInt64Array with little-endian
+ /// word order. Each arithmetic method operates on a Size-limb slice of every array
+ /// argument starting at the supplied offset; the caller is responsible for ensuring those
+ /// slices are in-bounds.
+ ///
+ /// Aliasing contract. The output buffer (AZ) may alias at most one
+ /// input, and only the first input. Specifically:
+ ///
+ /// - Multiply: AX may alias AZ (in-place
+ /// AZ = AZ * AY); AY must NOT alias AZ.
+ /// - Square / SquareN: AX may alias AZ
+ /// (in-place squaring).
+ ///
+ ///
+ /// Implementations may rely on the disallowed cases NOT occurring; consumers passing
+ /// disallowed aliases may produce arbitrary results.
+ ///
+ ///
+ IBinPolyMul = interface(IInterface)
+ ['{C1D2E3F4-A5B6-4789-ABCD-EF0123456702}']
+ /// Polynomial bit-length n.
+ function GetN: Int32;
+ /// Number of UInt64 limbs required to hold a polynomial of length N.
+ function GetSize: Int32;
+ ///
+ /// Compute AZ = AX * AY mod r(x). AX may alias AZ; AY must
+ /// not alias AZ. See the interface remarks for the full aliasing contract.
+ ///
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+ ///
+ /// Compute AZ = AX^2 mod r(x). AX may alias AZ (in-place squaring).
+ ///
+ procedure Square(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+ ///
+ /// Compute AZ = AX^(2^AN) mod r(x), i.e. repeated squarings.
+ /// AX may alias AZ (in-place repeated squaring).
+ ///
+ /// Number of squarings (must be positive).
+ procedure SquareN(const AX: TCryptoLibUInt64Array; AXOff: Int32; AN: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+ property N: Int32 read GetN;
+ property Size: Int32 read GetSize;
+ end;
+
+implementation
+
+end.
diff --git a/CryptoLib/src/Interfaces/Math/EC/ClpIECFieldElement.pas b/CryptoLib/src/Interfaces/Math/EC/ClpIECFieldElement.pas
index 5ab4e1d7..67068f4f 100644
--- a/CryptoLib/src/Interfaces/Math/EC/ClpIECFieldElement.pas
+++ b/CryptoLib/src/Interfaces/Math/EC/ClpIECFieldElement.pas
@@ -22,8 +22,8 @@ interface
uses
ClpBigInteger,
- ClpLongArray,
- ClpCryptoLibTypes;
+ ClpCryptoLibTypes,
+ ClpIF2mFieldData;
type
IECFieldElement = interface(IInterface)
@@ -94,14 +94,16 @@ interface
function GetK1: Int32;
function GetK2: Int32;
function GetK3: Int32;
- function GetX: TLongArray;
+ function GetX: TCryptoLibUInt64Array;
+ function GetF2mFieldData: IF2mFieldData;
property Representation: Int32 read GetRepresentation;
property M: Int32 read GetM;
property K1: Int32 read GetK1;
property K2: Int32 read GetK2;
property K3: Int32 read GetK3;
- property X: TLongArray read GetX;
+ property X: TCryptoLibUInt64Array read GetX;
+ property F2mFieldData: IF2mFieldData read GetF2mFieldData;
end;
implementation
diff --git a/CryptoLib/src/Interfaces/Math/EC/ClpIF2mFieldData.pas b/CryptoLib/src/Interfaces/Math/EC/ClpIF2mFieldData.pas
new file mode 100644
index 00000000..da9ef6fb
--- /dev/null
+++ b/CryptoLib/src/Interfaces/Math/EC/ClpIF2mFieldData.pas
@@ -0,0 +1,56 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIF2mFieldData;
+
+{$I ..\..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpIBinPolyInv;
+
+type
+ ///
+ /// Shared field arithmetic data for binary extension fields GF(2^m).
+ ///
+ ///
+ /// Bundles the reduction taps (Ks), multiply/invert primitives (Mul,
+ /// Inv), and field degree (M) used by F2m curve field elements.
+ ///
+ IF2mFieldData = interface(IInterface)
+ ['{D4E5F6A7-B8C9-4012-DEF0-123456789ABC}']
+ function GetM: Int32;
+ function GetKs: TCryptoLibInt32Array;
+ function GetMul: IBinPolyMul;
+ function GetInv: IBinPolyInv;
+ function GetK1: Int32;
+ function GetK2: Int32;
+ function GetK3: Int32;
+ property M: Int32 read GetM;
+ property Ks: TCryptoLibInt32Array read GetKs;
+ property Mul: IBinPolyMul read GetMul;
+ property Inv: IBinPolyInv read GetInv;
+ property K1: Int32 read GetK1;
+ property K2: Int32 read GetK2;
+ property K3: Int32 read GetK3;
+ end;
+
+implementation
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBase.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBase.pas
new file mode 100644
index 00000000..8a3278f2
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBase.pas
@@ -0,0 +1,172 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyMulBase;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpArrayUtilities,
+ ClpCryptoLibTypes,
+ ClpInterleave,
+ ClpIBinPolyMul;
+
+type
+ ///
+ /// Abstract base for IBinPolyMul implementations. Holds the shared state
+ /// (FN, FSize, FSizeExt, FReduce) and the squaring helpers
+ /// (Square, SquareN). Multiply is abstract and is supplied by
+ /// concrete subclasses.
+ ///
+ ///
+ ///
+ /// Polynomials are stored bit-packed in TCryptoLibUInt64Array with little-endian
+ /// word order. The caller is responsible for size-checking buffer arguments.
+ ///
+ ///
+ /// FSizeExt is always 2 * FSize. An extended product of two n-bit polynomials
+ /// fits in 2*n - 1 bits, so the topmost limb of the extended buffer may carry only
+ /// a few bits; the wasted single limb is preferable to tighter bound tracking.
+ ///
+ ///
+ /// The leaf multiply (below the Karatsuba recursion cutoff) is arbitrary-degree Karatsuba
+ /// over UInt64 words with a 16-entry-table 1x1 multiply.
+ ///
+ ///
+ TBinPolyMulBase = class abstract(TInterfacedObject, IBinPolyMul)
+ protected
+ FN: Int32;
+ FSize: Int32;
+ FSizeExt: Int32;
+ FReduce: IBinPolyReduce;
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ public
+ function GetN: Int32;
+ function GetSize: Int32;
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); virtual; abstract;
+ procedure Square(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+ procedure SquareN(const AX: TCryptoLibUInt64Array; AXOff: Int32; AN: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+ property N: Int32 read GetN;
+ property Size: Int32 read GetSize;
+ public
+ /// Decompose a bit position into its word index and bit offset within the word.
+ class procedure BitPos(ABit: Int32; out AW, ABitShift: Int32); static;
+ {$IFDEF DEBUG}
+ ///
+ /// Verify the per-call input contract of IBinPolyReduce.Reduce: Att must
+ /// contain no bits at positions above 2n - 2. Fully elided in release builds.
+ ///
+ class procedure DebugAssertReducePreconditions(AN: Int32;
+ const Att: TCryptoLibUInt64Array; AttOff: Int32); static;
+ {$ENDIF}
+ end;
+
+implementation
+
+{ TBinPolyMulBase }
+
+constructor TBinPolyMulBase.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create;
+ FN := AN;
+ FSize := (AN + 63) shr 6;
+ FSizeExt := FSize * 2;
+ FReduce := AReduce;
+end;
+
+function TBinPolyMulBase.GetN: Int32;
+begin
+ Result := FN;
+end;
+
+function TBinPolyMulBase.GetSize: Int32;
+begin
+ Result := FSize;
+end;
+
+procedure TBinPolyMulBase.Square(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+begin
+ SetLength(Ltt, FSizeExt);
+ try
+ TInterleave.Expand64To128(AX, AXOff, FSize, Ltt, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+ finally
+ TArrayUtilities.Fill(Ltt, 0, FSizeExt, 0);
+ end;
+end;
+
+procedure TBinPolyMulBase.SquareN(const AX: TCryptoLibUInt64Array; AXOff: Int32; AN: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+ LI: Int32;
+begin
+ if AN < 1 then
+ raise EArgumentOutOfRangeException.Create('n must be positive');
+
+ SetLength(Ltt, FSizeExt);
+ try
+ TInterleave.Expand64To128(AX, AXOff, FSize, Ltt, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+
+ for LI := AN - 1 downto 1 do
+ begin
+ TInterleave.Expand64To128(AZ, AZOff, FSize, Ltt, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+ end;
+ finally
+ TArrayUtilities.Fill(Ltt, 0, FSizeExt, 0);
+ end;
+end;
+
+class procedure TBinPolyMulBase.BitPos(ABit: Int32; out AW, ABitShift: Int32);
+begin
+ AW := ABit shr 6;
+ ABitShift := ABit and 63;
+end;
+
+{$IFDEF DEBUG}
+class procedure TBinPolyMulBase.DebugAssertReducePreconditions(AN: Int32;
+ const Att: TCryptoLibUInt64Array; AttOff: Int32);
+var
+ LSizeExt: Int32;
+ LSlackBit: Int32;
+ LSlackWord: Int32;
+ LSlack: UInt64;
+ LI: Int32;
+begin
+ LSizeExt := ((AN + 63) shr 6) shl 1;
+ LSlackBit := 2 * AN - 1;
+ LSlackWord := LSlackBit shr 6;
+ LSlack := Att[AttOff + LSlackWord] shr (LSlackBit and 63);
+ for LI := LSlackWord + 1 to LSizeExt - 1 do
+ LSlack := LSlack or Att[AttOff + LI];
+ System.Assert(LSlack = 0,
+ 'IBinPolyReduce.Reduce: tt has bits set above position 2n-2; slack must be zero.');
+end;
+{$ENDIF}
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBaseBinomialReduce.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBaseBinomialReduce.pas
new file mode 100644
index 00000000..4b52ac8e
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBaseBinomialReduce.pas
@@ -0,0 +1,146 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyMulBaseBinomialReduce;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpCryptoLibTypes,
+ ClpNat,
+ ClpBitOperations,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase;
+
+type
+ ///
+ /// Reduction by x^n + 1. The factory selects TUnaligned for the common case
+ /// ((n and 63) <> 0, partial top limb) or TAligned for n a multiple of 64
+ /// (full top limb, word-aligned fold).
+ ///
+ TBinPolyMulBaseBinomialReduce = class
+ public
+ type
+ ///
+ /// Sub-case for (n and 63) <> 0: the top result limb is partial. Folds the high
+ /// half up by excessBits = (-n) and 63 and masks the partial top limb.
+ ///
+ TUnaligned = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ public
+ constructor Create(AN: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+
+ ///
+ /// Sub-case for n a multiple of 64. The ring period is word-aligned, so x^n = 1
+ /// folds limb-for-limb with no shift or mask: Az = low xor high over
+ /// Size = n div 64 limbs.
+ ///
+ TAligned = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ public
+ constructor Create(AN: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ public
+ /// Select a binomial reducer for bit length .
+ class function Create(AN: Int32): IBinPolyReduce; static;
+ end;
+
+implementation
+
+{ TBinPolyMulBaseBinomialReduce }
+
+class function TBinPolyMulBaseBinomialReduce.Create(AN: Int32): IBinPolyReduce;
+begin
+ if (AN and 63) = 0 then
+ Result := TBinPolyMulBaseBinomialReduce.TAligned.Create(AN)
+ else
+ Result := TBinPolyMulBaseBinomialReduce.TUnaligned.Create(AN);
+end;
+
+{ TBinPolyMulBaseBinomialReduce.TUnaligned }
+
+constructor TBinPolyMulBaseBinomialReduce.TUnaligned.Create(AN: Int32);
+begin
+ inherited Create;
+ FN := AN;
+{$IFDEF DEBUG}
+ System.Assert((AN and 63) <> 0);
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseBinomialReduce.TUnaligned.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ LN: Int32;
+ LLast: Int32;
+ LSize: Int32;
+ LExcessBits: Int32;
+ LC: UInt64;
+begin
+ LN := FN;
+ {$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(LN, Att, AttOff);
+ {$ENDIF}
+
+ LLast := LN shr 6;
+ LSize := LLast + 1;
+ LExcessBits := -LN and 63;
+
+ LC := TNat.ShiftUpBitsXor64(LSize, Att, AttOff + LSize, LExcessBits, Att[AttOff + LLast],
+ Att, AttOff, Az, AzOff);
+{$IFDEF DEBUG}
+ System.Assert(LC = 0);
+{$ENDIF}
+ Az[AzOff + LLast] := Az[AzOff + LLast] and (UInt64.MaxValue shr LExcessBits);
+end;
+
+{ TBinPolyMulBaseBinomialReduce.TAligned }
+
+constructor TBinPolyMulBaseBinomialReduce.TAligned.Create(AN: Int32);
+begin
+ inherited Create;
+ FN := AN;
+{$IFDEF DEBUG}
+ System.Assert((AN and 63) = 0);
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseBinomialReduce.TAligned.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ LN: Int32;
+ LSize: Int32;
+begin
+ LN := FN;
+ {$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(LN, Att, AttOff);
+ {$ENDIF}
+
+ LSize := TBitOperations.Asr32(LN, 6);
+ TNat.Xor64(LSize, Att, AttOff, Att, AttOff + LSize, Az, AzOff);
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBasePentanomialReduce.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBasePentanomialReduce.pas
new file mode 100644
index 00000000..7dcafa7f
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBasePentanomialReduce.pas
@@ -0,0 +1,912 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyMulBasePentanomialReduce;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpBitOperations,
+ ClpCryptoLibTypes,
+ ClpNat,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase;
+
+type
+ ///
+ /// Pentanomial reduction by x^n + x^k3 + x^k2 + x^k1 + 1. The factory selects one
+ /// of several specialised implementations based on (n, k1, k2, k3).
+ ///
+ ///
+ /// Each bit at position p >= n folds via the "+1" tap and three "+x^ki" taps.
+ /// Factory dispatch branch order is critical — see the implementation comments in
+ /// Create.
+ ///
+ TBinPolyMulBasePentanomialReduce = class
+ public
+ type
+ TA = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA3 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA4 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA5 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA6 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA7 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA8 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TB = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TD = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TC = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TE = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK1: Int32;
+ FK2: Int32;
+ FK3: Int32;
+ public
+ constructor Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ public
+ ///
+ /// Select a pentanomial reducer for bit length and taps
+ /// , , .
+ ///
+ class function Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32): IBinPolyReduce; static;
+ end;
+
+implementation
+
+{ TBinPolyMulBasePentanomialReduce }
+
+class function TBinPolyMulBasePentanomialReduce.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32): IBinPolyReduce;
+begin
+ if (AN and 63) = 0 then
+ begin
+ if (AN - AK3 >= 64) and ((AK1 and 63) <> 0) and ((AK2 and 63) <> 0) and ((AK3 and 63) <> 0) then
+ Result := TBinPolyMulBasePentanomialReduce.TE.Create(AN, AK1, AK2, AK3)
+ else
+ Result := TBinPolyMulBasePentanomialReduce.TC.Create(AN, AK1, AK2, AK3);
+ Exit;
+ end;
+ if AN - AK3 < 64 then
+ begin
+ Result := TBinPolyMulBasePentanomialReduce.TC.Create(AN, AK1, AK2, AK3);
+ Exit;
+ end;
+ if AK3 < 64 then
+ begin
+ case AN div 32 of
+ 2: Result := TBinPolyMulBasePentanomialReduce.TA3.Create(AN, AK1, AK2, AK3);
+ 3: Result := TBinPolyMulBasePentanomialReduce.TA4.Create(AN, AK1, AK2, AK3);
+ 4: Result := TBinPolyMulBasePentanomialReduce.TA5.Create(AN, AK1, AK2, AK3);
+ 5: Result := TBinPolyMulBasePentanomialReduce.TA6.Create(AN, AK1, AK2, AK3);
+ 6: Result := TBinPolyMulBasePentanomialReduce.TA7.Create(AN, AK1, AK2, AK3);
+ 7: Result := TBinPolyMulBasePentanomialReduce.TA8.Create(AN, AK1, AK2, AK3);
+ else
+ Result := TBinPolyMulBasePentanomialReduce.TA.Create(AN, AK1, AK2, AK3);
+ end;
+ Exit;
+ end;
+ if (AK2 < 64) and ((AK3 and 63) <> 0) then
+ begin
+ Result := TBinPolyMulBasePentanomialReduce.TD.Create(AN, AK1, AK2, AK3);
+ Exit;
+ end;
+ if ((AK1 and 63) <> 0) and ((AK2 and 63) <> 0) and ((AK3 and 63) <> 0) then
+ begin
+ Result := TBinPolyMulBasePentanomialReduce.TB.Create(AN, AK1, AK2, AK3);
+ Exit;
+ end;
+ Result := TBinPolyMulBasePentanomialReduce.TC.Create(AN, AK1, AK2, AK3);
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TA }
+
+constructor TBinPolyMulBasePentanomialReduce.TA.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK3 < 64) and (AN - AK3 >= 64) and (AN div 32 >= 8));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TA.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+ LtHigh: UInt64;
+ LtLow: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n >= 4);
+{$ENDIF}
+ {Inter-iteration upper-half load cache: this iter's LtLow}
+ {(= tt[Lpos + Lw_n]) is exactly the next iter's LtHigh}
+ {(= tt[(Lpos - 1) + Lw_n + 1] = tt[Lpos + Lw_n]), so we carry it}
+ {forward in LtHigh instead of re-loading.}
+ Lpos := Lw_n;
+ LtHigh := Att[AttOff + Lpos + Lw_n + 1];
+ LtLow := Att[AttOff + Lpos + Lw_n ];
+ Lt := ((LtLow shr Ls_n)) or (TBitOperations.NegativeLeftShift64(LtHigh, -Ls_n));
+ Att[AttOff + Lpos ] := Att[AttOff + Lpos ] xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Att[AttOff + Lpos + 1] := Att[AttOff + Lpos + 1] xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ System.Dec(Lpos);
+ while Lpos >= 0 do
+ begin
+ LtHigh := LtLow;
+ LtLow := Att[AttOff + Lpos + Lw_n];
+ Lt := ((LtLow shr Ls_n)) or (TBitOperations.NegativeLeftShift64(LtHigh, -Ls_n));
+ Att[AttOff + Lpos] := Att[AttOff + Lpos] xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Att[AttOff + Lpos + 1] := Att[AttOff + Lpos + 1] xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ System.Dec(Lpos);
+ end;
+ TNat.Copy64(Lw_n, Att, AttOff, Az, AzOff);
+ Az[AzOff + Lw_n] := Att[AttOff + Lw_n] and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TA3 }
+
+constructor TBinPolyMulBasePentanomialReduce.TA3.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK3 < 64) and (AN - AK3 >= 64) and (AN div 32 = 2));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TA3.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 1);
+{$ENDIF}
+ {Load tt[0..2] into locals; tt[3] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ {Unrolled top-down word fold (Lpos = 1, 0). At Lpos = 1 the read}
+ {simplifies because tt[3] = 0.}
+ Lt := (Lt2 shr Ls_n);
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt1 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt2, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1 and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TA4 }
+
+constructor TBinPolyMulBasePentanomialReduce.TA4.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK3 < 64) and (AN - AK3 >= 64) and (AN div 32 = 3));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TA4.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 1);
+{$ENDIF}
+ {Load tt[0..3] into locals.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ {Unrolled top-down word fold (Lpos = 1, 0).}
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt1 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt2, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1 and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TA5 }
+
+constructor TBinPolyMulBasePentanomialReduce.TA5.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK3 < 64) and (AN - AK3 >= 64) and (AN div 32 = 4));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TA5.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 2);
+{$ENDIF}
+ {Load tt[0..4] into locals; tt[5] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ {Unrolled top-down word fold (Lpos = 2, 1, 0). At Lpos = 2 the read}
+ {simplifies because tt[5] = 0.}
+ Lt := (Lt4 shr Ls_n);
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt2 := Lt2 and not (UInt64.MaxValue shl Ls_n);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TA6 }
+
+constructor TBinPolyMulBasePentanomialReduce.TA6.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK3 < 64) and (AN - AK3 >= 64) and (AN div 32 = 5));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TA6.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 2);
+{$ENDIF}
+ {Load tt[0..5] into locals.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ {Unrolled top-down word fold (Lpos = 2, 1, 0).}
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt2 := Lt2 and not (UInt64.MaxValue shl Ls_n);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TA7 }
+
+constructor TBinPolyMulBasePentanomialReduce.TA7.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK3 < 64) and (AN - AK3 >= 64) and (AN div 32 = 6));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TA7.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt6: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 3);
+{$ENDIF}
+ {Load tt[0..6] into locals; tt[7] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ Lt6 := Att[AttOff + 6];
+ {Unrolled top-down word fold (Lpos = 3, 2, 1, 0). At Lpos = 3 the read}
+ {simplifies because tt[7] = 0.}
+ Lt := (Lt6 shr Ls_n);
+ Lt3 := Lt3 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt3 := Lt3 and not (UInt64.MaxValue shl Ls_n);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+ Az[AzOff + 3] := Lt3;
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TA8 }
+
+constructor TBinPolyMulBasePentanomialReduce.TA8.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK3 < 64) and (AN - AK3 >= 64) and (AN div 32 = 7));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TA8.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt6: UInt64;
+ Lt7: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 3);
+{$ENDIF}
+ {Load tt[0..7] into locals.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ Lt6 := Att[AttOff + 6];
+ Lt7 := Att[AttOff + 7];
+ {Unrolled top-down word fold (Lpos = 3, 2, 1, 0).}
+ Lt := ((Lt6 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt7, -Ls_n));
+ Lt3 := Lt3 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2) xor (Lt shl Lk3);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk1) xor TBitOperations.NegativeRightShift64(Lt, -Lk2) xor TBitOperations.NegativeRightShift64(Lt, -Lk3);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt3 := Lt3 and not (UInt64.MaxValue shl Ls_n);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+ Az[AzOff + 3] := Lt3;
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TB }
+
+constructor TBinPolyMulBasePentanomialReduce.TB.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK2 >= 64) and (AN - AK3 >= 64) and ((AK1 and 63) <> 0) and ((AK2 and 63) <> 0) and ((AK3 and 63) <> 0));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TB.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k1: Int32;
+ Ls_k1: Int32;
+ Lw_k2: Int32;
+ Ls_k2: Int32;
+ Lw_k3: Int32;
+ Ls_k3: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ TBinPolyMulBase.BitPos(Lk1, Lw_k1, Ls_k1);
+ TBinPolyMulBase.BitPos(Lk2, Lw_k2, Ls_k2);
+ TBinPolyMulBase.BitPos(Lk3, Lw_k3, Ls_k3);
+ Lpos := Lw_n;
+ repeat
+ Lt := (Att[AttOff + Lpos + Lw_n] shr Ls_n)
+ or TBitOperations.NegativeLeftShift64(Att[AttOff + Lpos + Lw_n + 1], -Ls_n);
+ Att[AttOff + Lpos] := Att[AttOff + Lpos] xor Lt;
+ Att[AttOff + Lpos + Lw_k1] := Att[AttOff + Lpos + Lw_k1] xor (Lt shl Ls_k1);
+ Att[AttOff + Lpos + Lw_k1 + 1] := Att[AttOff + Lpos + Lw_k1 + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k1);
+ Att[AttOff + Lpos + Lw_k2] := Att[AttOff + Lpos + Lw_k2] xor (Lt shl Ls_k2);
+ Att[AttOff + Lpos + Lw_k2 + 1] := Att[AttOff + Lpos + Lw_k2 + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k2);
+ Att[AttOff + Lpos + Lw_k3] := Att[AttOff + Lpos + Lw_k3] xor (Lt shl Ls_k3);
+ Att[AttOff + Lpos + Lw_k3 + 1] := Att[AttOff + Lpos + Lw_k3 + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k3);
+ System.Dec(Lpos);
+ until Lpos < 0;
+ TNat.Copy64(Lw_n, Att, AttOff, Az, AzOff);
+ Az[AzOff + Lw_n] := Att[AttOff + Lw_n] and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TD }
+
+constructor TBinPolyMulBasePentanomialReduce.TD.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK2 < 64) and (AK3 >= 64) and ((AK3 and 63) <> 0) and (AN - AK3 >= 64));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TD.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k3: Int32;
+ Ls_k3: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ TBinPolyMulBase.BitPos(Lk3, Lw_k3, Ls_k3);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n >= 2);
+{$ENDIF}
+ Lpos := Lw_n;
+ repeat
+ Lt := (Att[AttOff + Lpos + Lw_n] shr Ls_n)
+ or TBitOperations.NegativeLeftShift64(Att[AttOff + Lpos + Lw_n + 1], -Ls_n);
+ Att[AttOff + Lpos] := Att[AttOff + Lpos] xor Lt xor (Lt shl Lk1) xor (Lt shl Lk2);
+ Att[AttOff + Lpos + 1] := Att[AttOff + Lpos + 1] xor TBitOperations.NegativeRightShift64(Lt, -Lk1)
+ xor TBitOperations.NegativeRightShift64(Lt, -Lk2);
+ Att[AttOff + Lpos + Lw_k3] := Att[AttOff + Lpos + Lw_k3] xor (Lt shl Ls_k3);
+ Att[AttOff + Lpos + Lw_k3 + 1] := Att[AttOff + Lpos + Lw_k3 + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k3);
+ System.Dec(Lpos);
+ until Lpos < 0;
+ TNat.Copy64(Lw_n, Att, AttOff, Az, AzOff);
+ Az[AzOff + Lw_n] := Att[AttOff + Lw_n] and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TC }
+
+constructor TBinPolyMulBasePentanomialReduce.TC.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert((AN - AK3 < 64) or ((AK1 and 63) = 0) or ((AK2 and 63) = 0) or ((AK3 and 63) = 0));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TC.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ Lpos_0: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_0: Int32;
+ Ls_0: Int32;
+ Lw_k1: Int32;
+ Ls_k1: Int32;
+ Lw_k2: Int32;
+ Ls_k2: Int32;
+ Lw_k3: Int32;
+ Ls_k3: Int32;
+ Lw_top: Int32;
+ Ls_top: Int32;
+ Lbit_n: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ Lpos_0 := Ln - 1;
+ while Lpos_0 >= 0 do
+ begin
+ TBinPolyMulBase.BitPos(Lpos_0 + Ln, Lw_n, Ls_n);
+ Lbit_n := (Att[AttOff + Lw_n] shr Ls_n) and 1;
+ TBinPolyMulBase.BitPos(Lpos_0, Lw_0, Ls_0);
+ Att[AttOff + Lw_0] := Att[AttOff + Lw_0] xor (Lbit_n shl Ls_0);
+ TBinPolyMulBase.BitPos(Lpos_0 + Lk1, Lw_k1, Ls_k1);
+ Att[AttOff + Lw_k1] := Att[AttOff + Lw_k1] xor (Lbit_n shl Ls_k1);
+ TBinPolyMulBase.BitPos(Lpos_0 + Lk2, Lw_k2, Ls_k2);
+ Att[AttOff + Lw_k2] := Att[AttOff + Lw_k2] xor (Lbit_n shl Ls_k2);
+ TBinPolyMulBase.BitPos(Lpos_0 + Lk3, Lw_k3, Ls_k3);
+ Att[AttOff + Lw_k3] := Att[AttOff + Lw_k3] xor (Lbit_n shl Ls_k3);
+ System.Dec(Lpos_0);
+ end;
+ TBinPolyMulBase.BitPos(Ln, Lw_top, Ls_top);
+ TNat.Copy64(Lw_top, Att, AttOff, Az, AzOff);
+ {Ls_top = 0 (Ln a multiple of 64): the copy above already wrote the full top}
+ {limb (Lw_top = Lsize); no partial-limb mask, and z has no limb Lw_top to write.}
+ if Ls_top <> 0 then
+ Az[AzOff + Lw_top] := Att[AttOff + Lw_top] and not (UInt64.MaxValue shl Ls_top);
+end;
+
+{ TBinPolyMulBasePentanomialReduce.TE }
+
+constructor TBinPolyMulBasePentanomialReduce.TE.Create(AN: Int32; AK1: Int32; AK2: Int32; AK3: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK1 := AK1;
+ FK2 := AK2;
+ FK3 := AK3;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) = 0) and ((AK1 and 63) <> 0) and ((AK2 and 63) <> 0) and ((AK3 and 63) <> 0) and (AN - AK3 >= 64));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBasePentanomialReduce.TE.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk1: Int32;
+ Lk2: Int32;
+ Lk3: Int32;
+ Ln: Int32;
+ LW: Int32;
+ Lw_k1: Int32;
+ Ls_k1: Int32;
+ Lw_k2: Int32;
+ Ls_k2: Int32;
+ Lw_k3: Int32;
+ Ls_k3: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk1 := FK1;
+ Lk2 := FK2;
+ Lk3 := FK3;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ LW := (Ln shr 6);
+ TBinPolyMulBase.BitPos(Lk1, Lw_k1, Ls_k1);
+ TBinPolyMulBase.BitPos(Lk2, Lw_k2, Ls_k2);
+ TBinPolyMulBase.BitPos(Lk3, Lw_k3, Ls_k3);
+{$IFDEF DEBUG}
+ System.Assert((Ls_k1 <> 0) and (Ls_k2 <> 0) and (Ls_k3 <> 0) and (Lw_k3 <= LW - 2));
+{$ENDIF}
+ Lpos := LW - 1;
+ repeat
+ Lt := Att[AttOff + Lpos + LW];
+ Att[AttOff + Lpos] := Att[AttOff + Lpos] xor Lt;
+ Att[AttOff + Lpos + Lw_k1] := Att[AttOff + Lpos + Lw_k1] xor (Lt shl Ls_k1);
+ Att[AttOff + Lpos + Lw_k1 + 1] := Att[AttOff + Lpos + Lw_k1 + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k1);
+ Att[AttOff + Lpos + Lw_k2] := Att[AttOff + Lpos + Lw_k2] xor (Lt shl Ls_k2);
+ Att[AttOff + Lpos + Lw_k2 + 1] := Att[AttOff + Lpos + Lw_k2 + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k2);
+ Att[AttOff + Lpos + Lw_k3] := Att[AttOff + Lpos + Lw_k3] xor (Lt shl Ls_k3);
+ Att[AttOff + Lpos + Lw_k3 + 1] := Att[AttOff + Lpos + Lw_k3 + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k3);
+ System.Dec(Lpos);
+ until Lpos < 0;
+ TNat.Copy64(LW, Att, AttOff, Az, AzOff);
+end;
+
+end.
\ No newline at end of file
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBaseTrinomialReduce.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBaseTrinomialReduce.pas
new file mode 100644
index 00000000..f19dac43
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyMulBaseTrinomialReduce.pas
@@ -0,0 +1,1201 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyMulBaseTrinomialReduce;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpBitOperations,
+ ClpCryptoLibTypes,
+ ClpNat,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase;
+
+type
+ ///
+ /// Trinomial reduction by x^n + x^k + 1. The factory selects one of several
+ /// specialised implementations based on (n, k); each has a streamlined
+ /// Reduce body for its case.
+ ///
+ ///
+ ///
+ /// Each bit at position p >= n folds via the "+1" tap to position (p - n)
+ /// and via the "+x^k" tap to position (p - n + k). n need not be odd; the
+ /// word-at-a-time variants require a partial top limb ((n and 63) <> 0).
+ ///
+ ///
+ /// Factory dispatch branch order is critical — see the implementation comments in
+ /// Create. Sub-case naming: A-family (k < 64), B (k a multiple of
+ /// 64), C-family (k >= 64 with (k and 63) <> 0), D/E (bitwise /
+ /// word-aligned edge cases).
+ ///
+ ///
+ TBinPolyMulBaseTrinomialReduce = class
+ public
+ type
+ TA = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA3 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA4 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA5 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA6 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA7 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TA8 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TB = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TC = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TC5 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TC6 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TC7 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TC8 = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TD = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ TE = class sealed(TInterfacedObject, IBinPolyReduce)
+ private
+ FN: Int32;
+ FK: Int32;
+ public
+ constructor Create(AN: Int32; AK: Int32);
+ procedure Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+ end;
+ public
+ /// Select a trinomial reducer for bit length and tap .
+ class function Create(AN: Int32; AK: Int32): IBinPolyReduce; static;
+ end;
+
+implementation
+
+{ TBinPolyMulBaseTrinomialReduce }
+
+class function TBinPolyMulBaseTrinomialReduce.Create(AN: Int32; AK: Int32): IBinPolyReduce;
+begin
+ if (AN and 63) = 0 then
+ begin
+ if (AN - AK >= 64) and ((AK and 63) <> 0) then
+ Result := TBinPolyMulBaseTrinomialReduce.TE.Create(AN, AK)
+ else
+ Result := TBinPolyMulBaseTrinomialReduce.TD.Create(AN, AK);
+ Exit;
+ end;
+ if AN - AK < 64 then
+ begin
+ Result := TBinPolyMulBaseTrinomialReduce.TD.Create(AN, AK);
+ Exit;
+ end;
+ if AK < 64 then
+ begin
+ case AN div 32 of
+ 2: Result := TBinPolyMulBaseTrinomialReduce.TA3.Create(AN, AK);
+ 3: Result := TBinPolyMulBaseTrinomialReduce.TA4.Create(AN, AK);
+ 4: Result := TBinPolyMulBaseTrinomialReduce.TA5.Create(AN, AK);
+ 5: Result := TBinPolyMulBaseTrinomialReduce.TA6.Create(AN, AK);
+ 6: Result := TBinPolyMulBaseTrinomialReduce.TA7.Create(AN, AK);
+ 7: Result := TBinPolyMulBaseTrinomialReduce.TA8.Create(AN, AK);
+ else
+ Result := TBinPolyMulBaseTrinomialReduce.TA.Create(AN, AK);
+ end;
+ Exit;
+ end;
+ if (AK and 63) = 0 then
+ begin
+ Result := TBinPolyMulBaseTrinomialReduce.TB.Create(AN, AK);
+ Exit;
+ end;
+ case AN div 32 of
+ 4: Result := TBinPolyMulBaseTrinomialReduce.TC5.Create(AN, AK);
+ 5: Result := TBinPolyMulBaseTrinomialReduce.TC6.Create(AN, AK);
+ 6: Result := TBinPolyMulBaseTrinomialReduce.TC7.Create(AN, AK);
+ 7: Result := TBinPolyMulBaseTrinomialReduce.TC8.Create(AN, AK);
+ else
+ Result := TBinPolyMulBaseTrinomialReduce.TC.Create(AN, AK);
+ end;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TA }
+
+constructor TBinPolyMulBaseTrinomialReduce.TA.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK < 64) and (AN - AK >= 64) and (AN div 32 >= 8));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TA.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+ LtHigh: UInt64;
+ LtLow: UInt64;
+ LtFirst: UInt64;
+ Lr: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n >= 4);
+{$ENDIF}
+ {Inter-iteration register-carry. Lr holds the in-flight value of}
+ {tt[Lpos + 1] coming into each iteration. The upper-half load is also}
+ {carried across iterations via a 2-limb rolling window (LtHigh, LtLow):}
+ {this iter's LtLow (= tt[Lpos + Lw_n]) is exactly the next iter's LtHigh}
+ {(= tt[(Lpos - 1) + Lw_n + 1]), so each tt limb is loaded once.}
+ Lpos := Lw_n;
+ LtHigh := Att[AttOff + Lpos + Lw_n + 1];
+ LtLow := Att[AttOff + Lpos + Lw_n ];
+ LtFirst := ((LtLow shr Ls_n)) or (TBitOperations.NegativeLeftShift64(LtHigh, -Ls_n));
+ Lr := Att[AttOff + Lpos] xor LtFirst xor (LtFirst shl Lk);
+ Att[AttOff + Lpos + 1] := Att[AttOff + Lpos + 1] xor TBitOperations.NegativeRightShift64(LtFirst, -Lk);
+ System.Dec(Lpos);
+ while Lpos >= 0 do
+ begin
+ LtHigh := LtLow;
+ LtLow := Att[AttOff + Lpos + Lw_n];
+ Lt := ((LtLow shr Ls_n)) or (TBitOperations.NegativeLeftShift64(LtHigh, -Ls_n));
+ Lr := Lr xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Att[AttOff + Lpos + 1] := Lr;
+ Lr := Att[AttOff + Lpos] xor Lt xor (Lt shl Lk);
+ System.Dec(Lpos);
+ end;
+ Az[AzOff] := Lr;
+ TNat.Copy64(Lw_n - 1, Att, AttOff + 1, Az, AzOff + 1);
+ Az[AzOff + Lw_n] := Att[AttOff + Lw_n] and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TA3 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TA3.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK < 64) and (AN - AK >= 64) and (AN div 32 = 2));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TA3.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 1);
+{$ENDIF}
+ {Load tt[0..2] into locals; tt[3] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ {Unrolled top-down word fold (Lpos = 1, 0). At Lpos = 1 the read simplifies}
+ {because tt[3] = 0.}
+ Lt := (Lt2 shr Ls_n);
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt1 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt2, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1 and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TA4 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TA4.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK < 64) and (AN - AK >= 64) and (AN div 32 = 3));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TA4.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 1);
+{$ENDIF}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt1 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt2, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1 and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TA5 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TA5.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK < 64) and (AN - AK >= 64) and (AN div 32 = 4));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TA5.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 2);
+{$ENDIF}
+ {Load tt[0..4] into locals; tt[5] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ {Unrolled top-down word fold (Lpos = 2, 1, 0). With Lw_k = 0 (Lk < 64),}
+ {each iteration fuses "+1" and "+x^Lk low" into one XOR into tt[Lpos]}
+ {and one XOR into tt[Lpos + 1]. At Lpos = 2 the read simplifies because}
+ {tt[5] = 0.}
+ Lt := (Lt4 shr Ls_n);
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt2 := Lt2 and not (UInt64.MaxValue shl Ls_n);
+ {Write the three result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TA6 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TA6.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK < 64) and (AN - AK >= 64) and (AN div 32 = 5));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TA6.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 2);
+{$ENDIF}
+ {Load tt[0..5] into locals.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ {Unrolled top-down word fold (Lpos = 2, 1, 0). With Lw_k = 0 (Lk < 64),}
+ {each iteration fuses "+1" and "+x^Lk low" into one XOR into tt[Lpos]}
+ {and one XOR into tt[Lpos + 1].}
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt2 := Lt2 and not (UInt64.MaxValue shl Ls_n);
+ {Write the three result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TA7 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TA7.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK < 64) and (AN - AK >= 64) and (AN div 32 = 6));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TA7.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt6: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 3);
+{$ENDIF}
+ {Load tt[0..6] into locals; tt[7] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ Lt6 := Att[AttOff + 6];
+ {Unrolled top-down word fold (Lpos = 3, 2, 1, 0). With Lw_k = 0 (Lk < 64),}
+ {A's per-iteration writes collapse the "+1" and "+x^Lk" low-part into one}
+ {XOR into tt[Lpos] and one XOR into tt[Lpos + 1]. At Lpos = 3 the read}
+ {simplifies because tt[7] = 0.}
+ Lt := (Lt6 shr Ls_n);
+ Lt3 := Lt3 xor Lt xor (Lt shl Lk);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt3 := Lt3 and not (UInt64.MaxValue shl Ls_n);
+ {Write the four result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+ Az[AzOff + 3] := Lt3;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TA8 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TA8.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK < 64) and (AN - AK >= 64) and (AN div 32 = 7));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TA8.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt6: UInt64;
+ Lt7: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 3);
+{$ENDIF}
+ {Load tt[0..7] into locals.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ Lt6 := Att[AttOff + 6];
+ Lt7 := Att[AttOff + 7];
+ {Unrolled top-down word fold (Lpos = 3, 2, 1, 0). With Lw_k = 0 (Lk < 64),}
+ {each iteration fuses "+1" and "+x^Lk low" into one XOR into tt[Lpos] and}
+ {one XOR into tt[Lpos + 1].}
+ Lt := ((Lt6 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt7, -Ls_n));
+ Lt3 := Lt3 xor Lt xor (Lt shl Lk);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt xor (Lt shl Lk);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt xor (Lt shl Lk);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt xor (Lt shl Lk);
+ Lt1 := Lt1 xor TBitOperations.NegativeRightShift64(Lt, -Lk);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt3 := Lt3 and not (UInt64.MaxValue shl Ls_n);
+ {Write the four result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+ Az[AzOff + 3] := Lt3;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TB }
+
+constructor TBinPolyMulBaseTrinomialReduce.TB.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK >= 64) and ((AK and 63) = 0) and (AN - AK >= 64));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TB.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ Lw_k := (Lk shr 6);
+ Lpos := Lw_n;
+ repeat
+ Lt := (Att[AttOff + Lpos + Lw_n] shr Ls_n)
+ or TBitOperations.NegativeLeftShift64(Att[AttOff + Lpos + Lw_n + 1], -Ls_n);
+ Att[AttOff + Lpos] := Att[AttOff + Lpos] xor Lt;
+ Att[AttOff + Lpos + Lw_k] := Att[AttOff + Lpos + Lw_k] xor Lt;
+ System.Dec(Lpos);
+ until Lpos < 0;
+ TNat.Copy64(Lw_n, Att, AttOff, Az, AzOff);
+ Az[AzOff + Lw_n] := Att[AttOff + Lw_n] and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TC }
+
+constructor TBinPolyMulBaseTrinomialReduce.TC.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK >= 64) and ((AK and 63) <> 0) and (AN - AK >= 64) and (AN div 32 >= 8));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TC.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k: Int32;
+ Ls_k: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ TBinPolyMulBase.BitPos(Lk, Lw_k, Ls_k);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n >= 4);
+{$ENDIF}
+ Lpos := Lw_n;
+ repeat
+ Lt := (Att[AttOff + Lpos + Lw_n] shr Ls_n)
+ or TBitOperations.NegativeLeftShift64(Att[AttOff + Lpos + Lw_n + 1], -Ls_n);
+ Att[AttOff + Lpos] := Att[AttOff + Lpos] xor Lt;
+ Att[AttOff + Lpos + Lw_k] := Att[AttOff + Lpos + Lw_k] xor (Lt shl Ls_k);
+ Att[AttOff + Lpos + Lw_k + 1] := Att[AttOff + Lpos + Lw_k + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ System.Dec(Lpos);
+ until Lpos < 0;
+ TNat.Copy64(Lw_n, Att, AttOff, Az, AzOff);
+ Az[AzOff + Lw_n] := Att[AttOff + Lw_n] and not (UInt64.MaxValue shl Ls_n);
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TC5 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TC5.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK >= 64) and ((AK and 63) <> 0) and (AN - AK >= 64) and (AN div 32 = 4));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TC5.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k: Int32;
+ Ls_k: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ TBinPolyMulBase.BitPos(Lk, Lw_k, Ls_k);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 2);
+{$ENDIF}
+{$IFDEF DEBUG}
+ System.Assert(Lw_k = 1);
+{$ENDIF}
+ {Load tt[0..4] into locals; tt[5] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ {Unrolled top-down word fold (Lpos = 2, 1, 0). With Lw_k = 1, the "+x^Lk"}
+ {tap writes to tt[Lpos + 1] (low) and tt[Lpos + 2] (high). At Lpos = 2 the}
+ {read simplifies because tt[5] = 0.}
+ Lt := (Lt4 shr Ls_n);
+ Lt2 := Lt2 xor Lt;
+ Lt3 := Lt3 xor (Lt shl Ls_k);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt1 := Lt1 xor Lt;
+ Lt2 := Lt2 xor (Lt shl Ls_k);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt0 := Lt0 xor Lt;
+ Lt1 := Lt1 xor (Lt shl Ls_k);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt2 := Lt2 and not (UInt64.MaxValue shl Ls_n);
+ {Write the three result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TC6 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TC6.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK >= 64) and ((AK and 63) <> 0) and (AN - AK >= 64) and (AN div 32 = 5));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TC6.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k: Int32;
+ Ls_k: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ TBinPolyMulBase.BitPos(Lk, Lw_k, Ls_k);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 2);
+{$ENDIF}
+{$IFDEF DEBUG}
+ System.Assert(Lw_k = 1);
+{$ENDIF}
+ {Load tt[0..5] into locals.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ {Unrolled top-down word fold (Lpos = 2, 1, 0). With Lw_k = 1, the "+x^Lk"}
+ {tap writes to tt[Lpos + 1] (low) and tt[Lpos + 2] (high).}
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt2 := Lt2 xor Lt;
+ Lt3 := Lt3 xor (Lt shl Ls_k);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt1 := Lt1 xor Lt;
+ Lt2 := Lt2 xor (Lt shl Ls_k);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt2 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt3, -Ls_n));
+ Lt0 := Lt0 xor Lt;
+ Lt1 := Lt1 xor (Lt shl Ls_k);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt2 := Lt2 and not (UInt64.MaxValue shl Ls_n);
+ {Write the three result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TC7 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TC7.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK >= 64) and ((AK and 63) <> 0) and (AN - AK >= 64) and (AN div 32 = 6));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TC7.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k: Int32;
+ Ls_k: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt6: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ TBinPolyMulBase.BitPos(Lk, Lw_k, Ls_k);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 3);
+{$ENDIF}
+{$IFDEF DEBUG}
+ System.Assert((Lw_k = 1) or (Lw_k = 2));
+{$ENDIF}
+ {Load tt[0..6] into locals; tt[7] is slack (= 0 by contract) and elided.}
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ Lt6 := Att[AttOff + 6];
+ {Unrolled top-down word fold (Lpos = 3, 2, 1, 0). At Lpos = 3 the read}
+ {simplifies because tt[7] = 0. The destinations of the "+x^Lk" tap}
+ {depend on Lw_k (in [1, 2]), so the body branches once on Lw_k and}
+ {inlines the destinations in each arm.}
+ if Lw_k = 1 then
+ begin
+ Lt := (Lt6 shr Ls_n);
+ Lt3 := Lt3 xor Lt;
+ Lt4 := Lt4 xor (Lt shl Ls_k);
+ Lt5 := Lt5 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt;
+ Lt3 := Lt3 xor (Lt shl Ls_k);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt;
+ Lt2 := Lt2 xor (Lt shl Ls_k);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt;
+ Lt1 := Lt1 xor (Lt shl Ls_k);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ end
+ else
+ begin
+ Lt := (Lt6 shr Ls_n);
+ Lt3 := Lt3 xor Lt;
+ Lt5 := Lt5 xor (Lt shl Ls_k);
+ Lt6 := Lt6 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt;
+ Lt4 := Lt4 xor (Lt shl Ls_k);
+ Lt5 := Lt5 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt;
+ Lt3 := Lt3 xor (Lt shl Ls_k);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt;
+ Lt2 := Lt2 xor (Lt shl Ls_k);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ end;
+ {Mask off bits above position Ln - 1 in the top result limb.}
+ Lt3 := Lt3 and not (UInt64.MaxValue shl Ls_n);
+ {Write the four result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+ Az[AzOff + 3] := Lt3;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TC8 }
+
+constructor TBinPolyMulBaseTrinomialReduce.TC8.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) <> 0) and (AK >= 64) and ((AK and 63) <> 0) and (AN - AK >= 64) and (AN div 32 = 7));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TC8.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_k: Int32;
+ Ls_k: Int32;
+ Lt0: UInt64;
+ Lt1: UInt64;
+ Lt2: UInt64;
+ Lt3: UInt64;
+ Lt4: UInt64;
+ Lt5: UInt64;
+ Lt6: UInt64;
+ Lt7: UInt64;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ TBinPolyMulBase.BitPos(Ln, Lw_n, Ls_n);
+ TBinPolyMulBase.BitPos(Lk, Lw_k, Ls_k);
+{$IFDEF DEBUG}
+ System.Assert(Lw_n = 3);
+{$ENDIF}
+{$IFDEF DEBUG}
+ System.Assert((Lw_k = 1) or (Lw_k = 2));
+{$ENDIF}
+ //Load tt[0..7] into locals
+ Lt0 := Att[AttOff];
+ Lt1 := Att[AttOff + 1];
+ Lt2 := Att[AttOff + 2];
+ Lt3 := Att[AttOff + 3];
+ Lt4 := Att[AttOff + 4];
+ Lt5 := Att[AttOff + 5];
+ Lt6 := Att[AttOff + 6];
+ Lt7 := Att[AttOff + 7];
+ {Unrolled top-down word fold (Lpos = 3, 2, 1, 0). Each iteration:}
+ {Lt = (tt[Lpos+3] >> Ls_n) | (tt[Lpos+4] << -Ls_n)}
+ {tt[Lpos] ^= Lt (+1 tap)}
+ {tt[Lpos+Lw_k] ^= Lt << Ls_k (+x^Lk low)}
+ {tt[Lpos+Lw_k+1]^= Lt >> -Ls_k (+x^Lk high)}
+ {The destinations of the +x^Lk tap depend on Lw_k (in [1, 2]), so the body}
+ {branches once on Lw_k and inlines the destinations in each arm.}
+ if Lw_k = 1 then
+ begin
+ Lt := ((Lt6 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt7, -Ls_n));
+ Lt3 := Lt3 xor Lt;
+ Lt4 := Lt4 xor (Lt shl Ls_k);
+ Lt5 := Lt5 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt;
+ Lt3 := Lt3 xor (Lt shl Ls_k);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt;
+ Lt2 := Lt2 xor (Lt shl Ls_k);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt;
+ Lt1 := Lt1 xor (Lt shl Ls_k);
+ Lt2 := Lt2 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ end
+ else
+ begin
+ Lt := ((Lt6 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt7, -Ls_n));
+ Lt3 := Lt3 xor Lt;
+ Lt5 := Lt5 xor (Lt shl Ls_k);
+ Lt6 := Lt6 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt5 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt6, -Ls_n));
+ Lt2 := Lt2 xor Lt;
+ Lt4 := Lt4 xor (Lt shl Ls_k);
+ Lt5 := Lt5 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt4 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt5, -Ls_n));
+ Lt1 := Lt1 xor Lt;
+ Lt3 := Lt3 xor (Lt shl Ls_k);
+ Lt4 := Lt4 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ Lt := ((Lt3 shr Ls_n)) or (TBitOperations.NegativeLeftShift64(Lt4, -Ls_n));
+ Lt0 := Lt0 xor Lt;
+ Lt2 := Lt2 xor (Lt shl Ls_k);
+ Lt3 := Lt3 xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ end;
+ {Mask off the bits above position Ln - 1 in the top result limb.}
+ Lt3 := Lt3 and not (UInt64.MaxValue shl Ls_n);
+ {Write the four result limbs directly to z, bypassing the tt staging copy.}
+ Az[AzOff] := Lt0;
+ Az[AzOff + 1] := Lt1;
+ Az[AzOff + 2] := Lt2;
+ Az[AzOff + 3] := Lt3;
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TD }
+
+constructor TBinPolyMulBaseTrinomialReduce.TD.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert((AN - AK < 64) or (((AN and 63) = 0) and ((AK and 63) = 0)));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TD.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ Lpos_0: Int32;
+ Lw_n: Int32;
+ Ls_n: Int32;
+ Lw_0: Int32;
+ Ls_0: Int32;
+ Lw_k: Int32;
+ Ls_k: Int32;
+ Lw_top: Int32;
+ Ls_top: Int32;
+ Lbit_n: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ Lpos_0 := Ln - 1;
+ while Lpos_0 >= 0 do
+ begin
+ TBinPolyMulBase.BitPos(Lpos_0 + Ln, Lw_n, Ls_n);
+ Lbit_n := (Att[AttOff + Lw_n] shr Ls_n) and 1;
+ TBinPolyMulBase.BitPos(Lpos_0, Lw_0, Ls_0);
+ Att[AttOff + Lw_0] := Att[AttOff + Lw_0] xor (Lbit_n shl Ls_0);
+ TBinPolyMulBase.BitPos(Lpos_0 + Lk, Lw_k, Ls_k);
+ Att[AttOff + Lw_k] := Att[AttOff + Lw_k] xor (Lbit_n shl Ls_k);
+ System.Dec(Lpos_0);
+ end;
+ TBinPolyMulBase.BitPos(Ln, Lw_top, Ls_top);
+ TNat.Copy64(Lw_top, Att, AttOff, Az, AzOff);
+ {Ls_top = 0 (Ln a multiple of 64): the copy above already wrote the full top}
+ {limb (Lw_top = Lsize); no partial-limb mask, and z has no limb Lw_top to write.}
+ if Ls_top <> 0 then
+ Az[AzOff + Lw_top] := Att[AttOff + Lw_top] and not (UInt64.MaxValue shl Ls_top);
+end;
+
+{ TBinPolyMulBaseTrinomialReduce.TE }
+
+constructor TBinPolyMulBaseTrinomialReduce.TE.Create(AN: Int32; AK: Int32);
+begin
+ inherited Create;
+ FN := AN;
+ FK := AK;
+{$IFDEF DEBUG}
+ System.Assert(((AN and 63) = 0) and ((AK and 63) <> 0) and (AN - AK >= 64));
+{$ENDIF}
+end;
+
+procedure TBinPolyMulBaseTrinomialReduce.TE.Reduce(const Att: TCryptoLibUInt64Array; AttOff: Int32;
+ const Az: TCryptoLibUInt64Array; AzOff: Int32);
+var
+ Lk: Int32;
+ Ln: Int32;
+ LW: Int32;
+ Lw_k: Int32;
+ Ls_k: Int32;
+ Lpos: Int32;
+ Lt: UInt64;
+begin
+ Ln := FN;
+ Lk := FK;
+{$IFDEF DEBUG}
+ TBinPolyMulBase.DebugAssertReducePreconditions(Ln, Att, AttOff);
+{$ENDIF}
+ LW := (Ln shr 6);
+ TBinPolyMulBase.BitPos(Lk, Lw_k, Ls_k);
+{$IFDEF DEBUG}
+ System.Assert((Ls_k <> 0) and (Lw_k <= LW - 2));
+{$ENDIF}
+ Lpos := LW - 1;
+ repeat
+ Lt := Att[AttOff + Lpos + LW];
+ Att[AttOff + Lpos] := Att[AttOff + Lpos] xor Lt;
+ Att[AttOff + Lpos + Lw_k] := Att[AttOff + Lpos + Lw_k] xor (Lt shl Ls_k);
+ Att[AttOff + Lpos + Lw_k + 1] := Att[AttOff + Lpos + Lw_k + 1] xor TBitOperations.NegativeRightShift64(Lt, -Ls_k);
+ System.Dec(Lpos);
+ until Lpos < 0;
+ TNat.Copy64(LW, Att, AttOff, Az, AzOff);
+end;
+
+end.
\ No newline at end of file
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarBackend.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarBackend.pas
new file mode 100644
index 00000000..58bd4ffe
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarBackend.pas
@@ -0,0 +1,54 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyScalarBackend;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpIBinPolyMul,
+ ClpBinPolyScalarMedium,
+ ClpBinPolyScalarLarge;
+
+type
+ ///
+ /// Entry point for the scalar binary-polynomial multiply backend. Dispatches to
+ /// TBinPolyScalarMedium for sub-cutoff sizes (direct schoolbook leaf) and
+ /// TBinPolyScalarLarge for sizes at or above the Karatsuba cutoff.
+ ///
+ TBinPolyScalarBackend = class sealed
+ public
+ class function CreateBinPolyMul(AN: Int32; const AReduce: IBinPolyReduce): IBinPolyMul; static;
+ end;
+
+implementation
+
+{ TBinPolyScalarBackend }
+
+class function TBinPolyScalarBackend.CreateBinPolyMul(AN: Int32; const AReduce: IBinPolyReduce): IBinPolyMul;
+var
+ LSize: Int32;
+begin
+ LSize := (AN + 63) shr 6;
+ if LSize < TBinPolyScalarLarge.KaratsubaCutoff then
+ Result := TBinPolyScalarMedium.Create(AN, AReduce)
+ else
+ Result := TBinPolyScalarLarge.Create(AN, AReduce);
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarKernels.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarKernels.pas
new file mode 100644
index 00000000..d8f591bf
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarKernels.pas
@@ -0,0 +1,215 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyScalarKernels;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ Math,
+ ClpCryptoLibTypes,
+ ClpNat,
+ ClpBitOperations;
+
+type
+ ///
+ /// Scalar leaf multiply: arbitrary-degree Karatsuba with a 16-entry-table 1x1 multiply.
+ ///
+ TBinPolyScalarKernels = class sealed
+ private
+ class procedure ImplMulPostprocess(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32;
+ const AU: TCryptoLibUInt64Array); static;
+ class procedure ImplMulwAccTable(const AU: TCryptoLibUInt64Array; AX, AY: UInt64;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ class procedure ImplMulwAcc(const AU: TCryptoLibUInt64Array; AX, AY: UInt64;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ public
+ ///
+ /// Leaf multiply: write AX[AxOff..AxOff + ALen - 1] * AY[AyOff..AyOff + ALen - 1]
+ /// (carryless) into AZz[AzzOff..AzzOff + 2*ALen - 1], overwriting prior contents.
+ ///
+ class procedure ImplMul(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32); static;
+ end;
+
+implementation
+
+{ TBinPolyScalarKernels }
+
+class procedure TBinPolyScalarKernels.ImplMul(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32);
+var
+ LU: TCryptoLibUInt64Array;
+ LI: Int32;
+ LxBounds, LyBounds, LzzBounds: UInt64;
+begin
+ // Probe operand and output bounds early so callers get a range error at entry.
+ LxBounds := AX[AXOff + ALen - 1];
+ LyBounds := AY[AYOff + ALen - 1];
+ LzzBounds := AZz[AZzOff + 2 * ALen - 1];
+
+ SetLength(LU, 16);
+
+ for LI := 0 to ALen - 1 do
+ ImplMulwAccTable(LU, AX[AXOff + LI], AY[AYOff + LI], AZz, AZzOff + (LI shl 1));
+
+ ImplMulPostprocess(ALen, AX, AXOff, AY, AYOff, AZz, AZzOff, LU);
+end;
+
+class procedure TBinPolyScalarKernels.ImplMulPostprocess(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32;
+ const AU: TCryptoLibUInt64Array);
+var
+ LV0: UInt64;
+ LV1: UInt64;
+ LW: UInt64;
+ LI: Int32;
+ LLast: Int32;
+ LZPos: Int32;
+ LHi: Int32;
+ LLo: Int32;
+begin
+ LV0 := AZz[AZzOff];
+ LV1 := AZz[AZzOff + 1];
+ for LI := 1 to ALen - 1 do
+ begin
+ LV0 := LV0 xor AZz[AZzOff + (LI shl 1)];
+ AZz[AZzOff + LI] := LV0 xor LV1;
+ LV1 := LV1 xor AZz[AZzOff + (LI shl 1) + 1];
+ end;
+
+ LW := LV0 xor LV1;
+ TNat.Xor64(ALen, AZz, AZzOff, LW, AZz, AZzOff + ALen);
+
+ LLast := ALen - 1;
+ for LZPos := 1 to (LLast * 2) - 1 do
+ begin
+ LHi := Math.Min(LLast, LZPos);
+ LLo := LZPos - LHi;
+
+ while LLo < LHi do
+ begin
+ ImplMulwAcc(AU, AX[AXOff + LLo] xor AX[AXOff + LHi], AY[AYOff + LLo] xor AY[AYOff + LHi],
+ AZz, AZzOff + LZPos);
+ System.Inc(LLo);
+ System.Dec(LHi);
+ end;
+ end;
+end;
+
+class procedure TBinPolyScalarKernels.ImplMulwAccTable(const AU: TCryptoLibUInt64Array; AX, AY: UInt64;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ LH: UInt64;
+ LM: UInt64;
+ LN: UInt64;
+ LI: Int32;
+ LJ: UInt32;
+ LG: UInt64;
+ LL: UInt64;
+ LK: Int32;
+begin
+ LH := 0;
+ LM := AX;
+ LN := AY;
+
+ AU[1] := AY;
+ LI := 2;
+ while LI < 16 do
+ begin
+ AU[LI] := AU[LI div 2] shl 1;
+ AU[LI + 1] := AU[LI] xor AY;
+
+ LM := (LM and UInt64($FEFEFEFEFEFEFEFE)) shr 1;
+ LH := LH xor (LM and UInt64(TBitOperations.Asr64(Int64(LN), 63)));
+ LN := LN shl 1;
+ LI := LI + 2;
+ end;
+
+ LJ := UInt32(AX);
+ LL := AU[LJ and 15] xor (AU[(LJ shr 4) and 15] shl 4);
+ LK := 56;
+ repeat
+ LJ := UInt32(AX shr LK);
+ LG := AU[LJ and 15] xor (AU[(LJ shr 4) and 15] shl 4);
+ LL := LL xor (LG shl LK);
+ LH := LH xor TBitOperations.NegativeRightShift64(LG, -LK);
+ LK := LK - 8;
+ until LK <= 0;
+
+{$IFDEF DEBUG}
+ System.Assert(LH shr 63 = 0);
+{$ENDIF}
+
+ AZ[AZOff] := LL;
+ AZ[AZOff + 1] := LH;
+end;
+
+class procedure TBinPolyScalarKernels.ImplMulwAcc(const AU: TCryptoLibUInt64Array; AX, AY: UInt64;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ LH: UInt64;
+ LM: UInt64;
+ LN: UInt64;
+ LI: Int32;
+ LJ: UInt32;
+ LG: UInt64;
+ LL: UInt64;
+ LK: Int32;
+begin
+ LH := 0;
+ LM := AX;
+ LN := AY;
+
+ AU[1] := AY;
+ LI := 2;
+ while LI < 16 do
+ begin
+ AU[LI] := AU[LI div 2] shl 1;
+ AU[LI + 1] := AU[LI] xor AY;
+
+ LM := (LM and UInt64($FEFEFEFEFEFEFEFE)) shr 1;
+ LH := LH xor (LM and UInt64(TBitOperations.Asr64(Int64(LN), 63)));
+ LN := LN shl 1;
+ LI := LI + 2;
+ end;
+
+ LJ := UInt32(AX);
+ LL := AU[LJ and 15] xor (AU[(LJ shr 4) and 15] shl 4);
+ LK := 56;
+ repeat
+ LJ := UInt32(AX shr LK);
+ LG := AU[LJ and 15] xor (AU[(LJ shr 4) and 15] shl 4);
+ LL := LL xor (LG shl LK);
+ LH := LH xor TBitOperations.NegativeRightShift64(LG, -LK);
+ LK := LK - 8;
+ until LK <= 0;
+
+{$IFDEF DEBUG}
+ System.Assert(LH shr 63 = 0);
+{$ENDIF}
+
+ AZ[AZOff] := AZ[AZOff] xor LL;
+ AZ[AZOff + 1] := AZ[AZOff + 1] xor LH;
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarLarge.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarLarge.pas
new file mode 100644
index 00000000..7a8c8271
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarLarge.pas
@@ -0,0 +1,193 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyScalarLarge;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase,
+ ClpArrayUtilities,
+ ClpBinPolyScalarKernels;
+
+type
+ ///
+ /// Scalar IBinPolyMul implementation for sizes at or above
+ /// KaratsubaCutoff. Implements multiplication via in-class Karatsuba recursion whose
+ /// leaf is the scalar 16-entry-table multiply. The class name reflects the dispatch criterion
+ /// (large operand size); the algorithm inside is Karatsuba.
+ ///
+ ///
+ /// The recursion's scratch buffer is allocated per call and threaded through as a parameter,
+ /// so instances are safe to use concurrently.
+ ///
+ TBinPolyScalarLarge = class sealed(TBinPolyMulBase)
+ strict private
+ class function KaratsubaScratchSize(ALen: Int32): Int32; static;
+ class procedure ImplLeaf(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32); static;
+ class procedure ImplKaratsuba(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32;
+ const AScratch: TCryptoLibUInt64Array; AScratchOff: Int32); static;
+ public
+ ///
+ /// Karatsuba cutoff (in machine words). Below this, the table-based
+ /// TBinPolyScalarKernels.ImplMul leaf is called directly; above it,
+ /// ImplKaratsuba recurses by halving. Must be >= 2 for recursion termination.
+ ///
+ const
+ KaratsubaCutoff = 8;
+
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+implementation
+
+{ TBinPolyScalarLarge }
+
+constructor TBinPolyScalarLarge.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyScalarLarge.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+ LScratch: TCryptoLibUInt64Array;
+ LScratchSize: Int32;
+begin
+ LScratchSize := KaratsubaScratchSize(FSize);
+ SetLength(Ltt, FSizeExt);
+ SetLength(LScratch, LScratchSize);
+ try
+ ImplKaratsuba(FSize, AX, AXOff, AY, AYOff, Ltt, 0, LScratch, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+ finally
+ TArrayUtilities.Fill(LScratch, 0, LScratchSize, 0);
+ TArrayUtilities.Fill(Ltt, 0, FSizeExt, 0);
+ end;
+end;
+
+class function TBinPolyScalarLarge.KaratsubaScratchSize(ALen: Int32): Int32;
+var
+ LTotal: Int32;
+ LLen: Int32;
+begin
+{$IFDEF DEBUG}
+ System.Assert(KaratsubaCutoff >= 2);
+{$ENDIF}
+ LTotal := 0;
+ LLen := ALen;
+ while LLen >= KaratsubaCutoff do
+ begin
+ LLen := (LLen + 1) shr 1;
+ LTotal := LTotal + LLen;
+ end;
+ Result := LTotal shl 1;
+end;
+
+class procedure TBinPolyScalarLarge.ImplLeaf(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32);
+begin
+ TBinPolyScalarKernels.ImplMul(ALen, AX, AXOff, AY, AYOff, AZz, AZzOff);
+end;
+
+class procedure TBinPolyScalarLarge.ImplKaratsuba(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32;
+ const AScratch: TCryptoLibUInt64Array; AScratchOff: Int32);
+var
+ LM: Int32;
+ LN: Int32;
+ LNx2: Int32;
+ LMx2: Int32;
+ LZMidOffset: Int32;
+ LChildScratchOff: Int32;
+ LI: Int32;
+ LU: UInt64;
+begin
+ if ALen < KaratsubaCutoff then
+ begin
+ ImplLeaf(ALen, AX, AXOff, AY, AYOff, AZz, AZzOff);
+ Exit;
+ end;
+
+ if (ALen and 1) = 0 then
+ begin
+ LM := ALen shr 1;
+ LZMidOffset := AScratchOff;
+ LChildScratchOff := AScratchOff + 2 * LM;
+
+ for LI := 0 to LM - 1 do
+ begin
+ AZz[AZzOff + LI] := AX[AXOff + LI] xor AX[AXOff + LM + LI];
+ AZz[AZzOff + LM + LI] := AY[AYOff + LI] xor AY[AYOff + LM + LI];
+ end;
+
+ ImplKaratsuba(LM, AZz, AZzOff, AZz, AZzOff + LM, AScratch, LZMidOffset, AScratch, LChildScratchOff);
+ ImplKaratsuba(LM, AX, AXOff, AY, AYOff, AZz, AZzOff, AScratch, LChildScratchOff);
+ ImplKaratsuba(LM, AX, AXOff + LM, AY, AYOff + LM, AZz, AZzOff + ALen, AScratch, LChildScratchOff);
+
+ for LI := 0 to LM - 1 do
+ begin
+ LU := AZz[AZzOff + LM + LI] xor AZz[AZzOff + ALen + LI];
+ AZz[AZzOff + LM + LI] := LU xor AZz[AZzOff + LI] xor AScratch[LZMidOffset + LI];
+ AZz[AZzOff + ALen + LI] := LU xor AZz[AZzOff + ALen + LM + LI] xor AScratch[LZMidOffset + LM + LI];
+ end;
+ end
+ else
+ begin
+ LN := ALen shr 1;
+ LM := LN + 1;
+ LNx2 := LN shl 1;
+ LMx2 := LM shl 1;
+ LZMidOffset := AScratchOff;
+ LChildScratchOff := AScratchOff + LMx2;
+
+ for LI := 0 to LN - 1 do
+ begin
+ AZz[AZzOff + LI] := AX[AXOff + LI] xor AX[AXOff + LN + LI];
+ AZz[AZzOff + LM + LI] := AY[AYOff + LI] xor AY[AYOff + LN + LI];
+ end;
+ AZz[AZzOff + LN] := AX[AXOff + LNx2];
+ AZz[AZzOff + LM + LN] := AY[AYOff + LNx2];
+
+ ImplKaratsuba(LM, AZz, AZzOff, AZz, AZzOff + LM, AScratch, LZMidOffset, AScratch, LChildScratchOff);
+ ImplKaratsuba(LN, AX, AXOff, AY, AYOff, AZz, AZzOff, AScratch, LChildScratchOff);
+ ImplKaratsuba(LM, AX, AXOff + LN, AY, AYOff + LN, AZz, AZzOff + LNx2, AScratch, LChildScratchOff);
+
+ for LI := 0 to LN - 1 do
+ begin
+ LU := AZz[AZzOff + LN + LI] xor AZz[AZzOff + LNx2 + LI];
+ AZz[AZzOff + LN + LI] := LU xor AZz[AZzOff + LI] xor AScratch[LZMidOffset + LI];
+ AZz[AZzOff + LNx2 + LI] := LU xor AZz[AZzOff + LNx2 + LN + LI] xor AScratch[LZMidOffset + LN + LI];
+ end;
+
+ AZz[AZzOff + LN + LNx2] := AZz[AZzOff + LN + LNx2] xor AScratch[LZMidOffset + LNx2] xor AZz[AZzOff + LNx2 + LNx2];
+ AZz[AZzOff + LN + LNx2 + 1] := AZz[AZzOff + LN + LNx2 + 1] xor AScratch[LZMidOffset + LNx2 + 1] xor AZz[AZzOff + LNx2 + LNx2 + 1];
+ end;
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarMedium.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarMedium.pas
new file mode 100644
index 00000000..c86614a5
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyScalarMedium.pas
@@ -0,0 +1,68 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyScalarMedium;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase,
+ ClpArrayUtilities,
+ ClpBinPolyScalarKernels;
+
+type
+ ///
+ /// Scalar IBinPolyMul implementation for sizes below
+ /// TBinPolyScalarLarge.KaratsubaCutoff: small enough that the schoolbook leaf beats a
+ /// Karatsuba descent. Multiply is a single call to
+ /// TBinPolyScalarKernels.ImplMul followed by reduction.
+ ///
+ TBinPolyScalarMedium = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+implementation
+
+{ TBinPolyScalarMedium }
+
+constructor TBinPolyScalarMedium.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyScalarMedium.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+begin
+ SetLength(Ltt, FSizeExt);
+ try
+ TBinPolyScalarKernels.ImplMul(FSize, AX, AXOff, AY, AYOff, Ltt, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+ finally
+ TArrayUtilities.Fill(Ltt, 0, FSizeExt, 0);
+ end;
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Backend.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Backend.pas
new file mode 100644
index 00000000..9fc7b8c6
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Backend.pas
@@ -0,0 +1,85 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyX86V128Backend;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpIBinPolyMul,
+ ClpCpuFeatures,
+ ClpIntrinsicsVector,
+ ClpBinPolyX86V128Sizes,
+ ClpBinPolyX86V128Medium,
+ ClpBinPolyX86V128Large,
+ ClpCryptoLibTypes;
+
+type
+ ///
+ /// Entry point for the x86/V128 binary-polynomial multiply backend.
+ ///
+ TBinPolyX86V128Backend = class sealed
+ public
+ class function IsEnabled: Boolean; static;
+ class function CreateBinPolyMul(AN: Int32; const AReduce: IBinPolyReduce): IBinPolyMul; static;
+ end;
+
+implementation
+
+{ TBinPolyX86V128Backend }
+
+class function TBinPolyX86V128Backend.IsEnabled: Boolean;
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+ Result := TCpuFeatures.X86.HasPCLMULQDQ and TIntrinsicsVector.IsPacked;
+{$ELSE}
+ Result := False;
+{$ENDIF}
+end;
+
+class function TBinPolyX86V128Backend.CreateBinPolyMul(AN: Int32; const AReduce: IBinPolyReduce): IBinPolyMul;
+var
+ LSize: Int32;
+begin
+ if not IsEnabled then
+ raise EInvalidOperationCryptoLibException.Create('X86.V128 backend requires PCLMULQDQ support on this target.');
+
+ LSize := (AN + 63) shr 6;
+ case LSize of
+ 1: Result := TBinPolyX86V128Size1.Create(AN, AReduce);
+ 2: Result := TBinPolyX86V128Size2.Create(AN, AReduce);
+ 3: Result := TBinPolyX86V128Size3.Create(AN, AReduce);
+ 4: Result := TBinPolyX86V128Size4.Create(AN, AReduce);
+ 5: Result := TBinPolyX86V128Size5.Create(AN, AReduce);
+ 6: Result := TBinPolyX86V128Size6.Create(AN, AReduce);
+ 7: Result := TBinPolyX86V128Size7.Create(AN, AReduce);
+ 8: Result := TBinPolyX86V128Size8.Create(AN, AReduce);
+ 9: Result := TBinPolyX86V128Size9.Create(AN, AReduce);
+ 10: Result := TBinPolyX86V128Size10.Create(AN, AReduce);
+ else
+ if LSize >= TBinPolyX86V128Large.KaratsubaCutoff then
+ Result := TBinPolyX86V128Large.Create(AN, AReduce)
+ else if (LSize and 1) = 0 then
+ Result := TBinPolyX86V128MediumEven.Create(AN, AReduce)
+ else
+ Result := TBinPolyX86V128MediumOdd.Create(AN, AReduce);
+ end;
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Kernels.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Kernels.pas
new file mode 100644
index 00000000..e2434a00
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Kernels.pas
@@ -0,0 +1,123 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyX86V128Kernels;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpCryptoLibTypes;
+
+type
+ ///
+ /// x86/V128 binary-polynomial multiply kernels. Hot paths are implemented in
+ /// Include/Simd/BinPoly/.
+ ///
+ TBinPolyX86V128Kernels = class sealed
+ public
+ class procedure ImplMulSmall(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32); static;
+ class procedure ImplMulEven(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32); static;
+ class procedure ImplMulOdd(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32); static;
+ end;
+
+implementation
+
+{$IFDEF CRYPTOLIB_X86_SIMD}
+procedure BinPolyPclmulImplMulSmall(ALen: Int32; PX, PY, PZz: Pointer);
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\SimdProc4Begin_x86_64.inc}
+{$I ..\..\Include\Simd\BinPoly\BinPolyPclmulImplMulSmall_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\SimdProc4Begin_i386.inc}
+{$I ..\..\Include\Simd\BinPoly\BinPolyPclmulImplMulSmall_i386.inc}
+{$ENDIF}
+end;
+
+procedure BinPolyPclmulImplMulEven(ALen: Int32; PX, PY, PZz: Pointer);
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\SimdProc4Begin_x86_64.inc}
+{$I ..\..\Include\Simd\BinPoly\BinPolyPclmulImplMulEven_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\SimdProc4Begin_i386.inc}
+{$I ..\..\Include\Simd\BinPoly\BinPolyPclmulImplMulEven_i386.inc}
+{$ENDIF}
+end;
+
+procedure BinPolyPclmulImplMulOdd(ALen: Int32; PX, PY, PZz: Pointer);
+{$IFDEF CRYPTOLIB_X86_64_ASM}
+{$I ..\..\Include\Simd\Common\SimdProc4Begin_x86_64.inc}
+{$I ..\..\Include\Simd\BinPoly\BinPolyPclmulImplMulOdd_x86_64.inc}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_I386_ASM}
+{$I ..\..\Include\Simd\Common\SimdProc4Begin_i386.inc}
+{$I ..\..\Include\Simd\BinPoly\BinPolyPclmulImplMulOdd_i386.inc}
+{$ENDIF}
+end;
+{$ENDIF CRYPTOLIB_X86_SIMD}
+
+class procedure TBinPolyX86V128Kernels.ImplMulSmall(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+{$IFDEF DEBUG}
+ System.Assert((ALen >= 1) and (ALen <= 10));
+{$ENDIF}
+ BinPolyPclmulImplMulSmall(ALen, @AX[AXOff], @AY[AYOff], @AZz[AZzOff]);
+{$ELSE}
+ raise ENotImplemented.Create('x86/V128 ImplMulSmall is not available on this target');
+{$ENDIF}
+end;
+
+class procedure TBinPolyX86V128Kernels.ImplMulEven(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+{$IFDEF DEBUG}
+ System.Assert((ALen and 1) = 0);
+ System.Assert(ALen >= 2);
+{$ENDIF}
+ BinPolyPclmulImplMulEven(ALen, @AX[AXOff], @AY[AYOff], @AZz[AZzOff]);
+{$ELSE}
+ raise ENotImplemented.Create('x86/V128 ImplMulEven is not available on this target');
+{$ENDIF}
+end;
+
+class procedure TBinPolyX86V128Kernels.ImplMulOdd(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32);
+begin
+{$IFDEF CRYPTOLIB_X86_SIMD}
+{$IFDEF DEBUG}
+ System.Assert((ALen and 1) = 1);
+ System.Assert(ALen >= 1);
+{$ENDIF}
+ BinPolyPclmulImplMulOdd(ALen, @AX[AXOff], @AY[AYOff], @AZz[AZzOff]);
+{$ELSE}
+ raise ENotImplemented.Create('x86/V128 ImplMulOdd is not available on this target');
+{$ENDIF}
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Large.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Large.pas
new file mode 100644
index 00000000..f0cb0bc9
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Large.pas
@@ -0,0 +1,184 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyX86V128Large;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase,
+ ClpArrayUtilities,
+ ClpBinPolyX86V128Kernels;
+
+type
+ ///
+ /// x86/V128 IBinPolyMul for sizes at or above KaratsubaCutoff (32 limbs).
+ ///
+ TBinPolyX86V128Large = class sealed(TBinPolyMulBase)
+ public
+ const
+ KaratsubaCutoff = 32;
+ strict private
+ class function KaratsubaScratchSize(ALen: Int32): Int32; static;
+ class procedure ImplLeaf(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32); static;
+ class procedure ImplKaratsuba(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZz: TCryptoLibUInt64Array; AZzOff: Int32;
+ const AScratch: TCryptoLibUInt64Array; AScratchOff: Int32); static;
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+implementation
+
+{ TBinPolyX86V128Large }
+
+constructor TBinPolyX86V128Large.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Large.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+ LScratch: TCryptoLibUInt64Array;
+ LScratchSize: Int32;
+begin
+ LScratchSize := KaratsubaScratchSize(FSize);
+ SetLength(Ltt, FSizeExt);
+ SetLength(LScratch, LScratchSize);
+ try
+ ImplKaratsuba(FSize, AX, AXOff, AY, AYOff, Ltt, 0, LScratch, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+ finally
+ TArrayUtilities.Fill(LScratch, 0, LScratchSize, 0);
+ TArrayUtilities.Fill(Ltt, 0, FSizeExt, 0);
+ end;
+end;
+
+class function TBinPolyX86V128Large.KaratsubaScratchSize(ALen: Int32): Int32;
+var
+ LTotal: Int32;
+ LLen: Int32;
+begin
+{$IFDEF DEBUG}
+ System.Assert(KaratsubaCutoff >= 2);
+{$ENDIF}
+ LTotal := 0;
+ LLen := ALen;
+ while LLen >= KaratsubaCutoff do
+ begin
+ LLen := (LLen + 1) shr 1;
+ LTotal := LTotal + LLen;
+ end;
+ Result := LTotal shl 1;
+end;
+
+class procedure TBinPolyX86V128Large.ImplLeaf(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32);
+begin
+ if (ALen and 1) = 0 then
+ TBinPolyX86V128Kernels.ImplMulEven(ALen, AX, AXOff, AY, AYOff, AZz, AZzOff)
+ else
+ TBinPolyX86V128Kernels.ImplMulOdd(ALen, AX, AXOff, AY, AYOff, AZz, AZzOff);
+end;
+
+class procedure TBinPolyX86V128Large.ImplKaratsuba(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZz: TCryptoLibUInt64Array; AZzOff: Int32;
+ const AScratch: TCryptoLibUInt64Array; AScratchOff: Int32);
+var
+ LM: Int32;
+ LN: Int32;
+ LNx2: Int32;
+ LMx2: Int32;
+ LZMidOffset: Int32;
+ LChildScratchOff: Int32;
+ LI: Int32;
+ LU: UInt64;
+begin
+ if ALen < KaratsubaCutoff then
+ begin
+ ImplLeaf(ALen, AX, AXOff, AY, AYOff, AZz, AZzOff);
+ Exit;
+ end;
+
+ if (ALen and 1) = 0 then
+ begin
+ LM := ALen shr 1;
+ LZMidOffset := AScratchOff;
+ LChildScratchOff := AScratchOff + 2 * LM;
+
+ for LI := 0 to LM - 1 do
+ begin
+ AZz[AZzOff + LI] := AX[AXOff + LI] xor AX[AXOff + LM + LI];
+ AZz[AZzOff + LM + LI] := AY[AYOff + LI] xor AY[AYOff + LM + LI];
+ end;
+
+ ImplKaratsuba(LM, AZz, AZzOff, AZz, AZzOff + LM, AScratch, LZMidOffset, AScratch, LChildScratchOff);
+ ImplKaratsuba(LM, AX, AXOff, AY, AYOff, AZz, AZzOff, AScratch, LChildScratchOff);
+ ImplKaratsuba(LM, AX, AXOff + LM, AY, AYOff + LM, AZz, AZzOff + ALen, AScratch, LChildScratchOff);
+
+ for LI := 0 to LM - 1 do
+ begin
+ LU := AZz[AZzOff + LM + LI] xor AZz[AZzOff + ALen + LI];
+ AZz[AZzOff + LM + LI] := LU xor AZz[AZzOff + LI] xor AScratch[LZMidOffset + LI];
+ AZz[AZzOff + ALen + LI] := LU xor AZz[AZzOff + ALen + LM + LI] xor AScratch[LZMidOffset + LM + LI];
+ end;
+ end
+ else
+ begin
+ LN := ALen shr 1;
+ LM := LN + 1;
+ LNx2 := LN shl 1;
+ LMx2 := LM shl 1;
+ LZMidOffset := AScratchOff;
+ LChildScratchOff := AScratchOff + LMx2;
+
+ for LI := 0 to LN - 1 do
+ begin
+ AZz[AZzOff + LI] := AX[AXOff + LI] xor AX[AXOff + LN + LI];
+ AZz[AZzOff + LM + LI] := AY[AYOff + LI] xor AY[AYOff + LN + LI];
+ end;
+ AZz[AZzOff + LN] := AX[AXOff + LNx2];
+ AZz[AZzOff + LM + LN] := AY[AYOff + LNx2];
+
+ ImplKaratsuba(LM, AZz, AZzOff, AZz, AZzOff + LM, AScratch, LZMidOffset, AScratch, LChildScratchOff);
+ ImplKaratsuba(LN, AX, AXOff, AY, AYOff, AZz, AZzOff, AScratch, LChildScratchOff);
+ ImplKaratsuba(LM, AX, AXOff + LN, AY, AYOff + LN, AZz, AZzOff + LNx2, AScratch, LChildScratchOff);
+
+ for LI := 0 to LN - 1 do
+ begin
+ LU := AZz[AZzOff + LN + LI] xor AZz[AZzOff + LNx2 + LI];
+ AZz[AZzOff + LN + LI] := LU xor AZz[AZzOff + LI] xor AScratch[LZMidOffset + LI];
+ AZz[AZzOff + LNx2 + LI] := LU xor AZz[AZzOff + LNx2 + LN + LI] xor AScratch[LZMidOffset + LN + LI];
+ end;
+
+ AZz[AZzOff + LN + LNx2] := AZz[AZzOff + LN + LNx2] xor AScratch[LZMidOffset + LNx2] xor AZz[AZzOff + LNx2 + LNx2];
+ AZz[AZzOff + LN + LNx2 + 1] := AZz[AZzOff + LN + LNx2 + 1] xor AScratch[LZMidOffset + LNx2 + 1] xor AZz[AZzOff + LNx2 + LNx2 + 1];
+ end;
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Medium.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Medium.pas
new file mode 100644
index 00000000..80296566
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Medium.pas
@@ -0,0 +1,105 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyX86V128Medium;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase,
+ ClpArrayUtilities,
+ ClpBinPolyX86V128Kernels;
+
+type
+ ///
+ /// x86/V128 IBinPolyMul for even limb counts in (10, KaratsubaCutoff).
+ ///
+ TBinPolyX86V128MediumEven = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ ///
+ /// x86/V128 IBinPolyMul for odd limb counts in (10, KaratsubaCutoff).
+ ///
+ TBinPolyX86V128MediumOdd = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+implementation
+
+{ TBinPolyX86V128MediumEven }
+
+constructor TBinPolyX86V128MediumEven.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+{$IFDEF DEBUG}
+ System.Assert((FSize and 1) = 0);
+ System.Assert((FSize > 10) and (FSize < 32));
+{$ENDIF}
+end;
+
+procedure TBinPolyX86V128MediumEven.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+begin
+ SetLength(Ltt, FSizeExt);
+ try
+ TBinPolyX86V128Kernels.ImplMulEven(FSize, AX, AXOff, AY, AYOff, Ltt, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+ finally
+ TArrayUtilities.Fill(Ltt, 0, FSizeExt, 0);
+ end;
+end;
+
+{ TBinPolyX86V128MediumOdd }
+
+constructor TBinPolyX86V128MediumOdd.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+{$IFDEF DEBUG}
+ System.Assert((FSize and 1) = 1);
+ System.Assert((FSize > 10) and (FSize < 32));
+{$ENDIF}
+end;
+
+procedure TBinPolyX86V128MediumOdd.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+begin
+ SetLength(Ltt, FSizeExt);
+ try
+ TBinPolyX86V128Kernels.ImplMulOdd(FSize, AX, AXOff, AY, AYOff, Ltt, 0);
+ FReduce.Reduce(Ltt, 0, AZ, AZOff);
+ finally
+ TArrayUtilities.Fill(Ltt, 0, FSizeExt, 0);
+ end;
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Sizes.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Sizes.pas
new file mode 100644
index 00000000..a185c001
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolyX86V128Sizes.pas
@@ -0,0 +1,259 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolyX86V128Sizes;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpBinPolyMulBase,
+ ClpArrayUtilities,
+ ClpBinPolyX86V128Kernels;
+
+type
+ TBinPolyX86V128Size1 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size2 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size3 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size4 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size5 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size6 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size7 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size8 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size9 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+ TBinPolyX86V128Size10 = class sealed(TBinPolyMulBase)
+ public
+ constructor Create(AN: Int32; const AReduce: IBinPolyReduce);
+ procedure Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); override;
+ end;
+
+implementation
+
+procedure MultiplySmallFixed(ASmallLen: Int32; const AReduce: IBinPolyReduce; ASizeExt: Int32;
+ const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Ltt: TCryptoLibUInt64Array;
+begin
+ SetLength(Ltt, ASizeExt);
+ try
+ TBinPolyX86V128Kernels.ImplMulSmall(ASmallLen, AX, AXOff, AY, AYOff, Ltt, 0);
+ AReduce.Reduce(Ltt, 0, AZ, AZOff);
+ finally
+ TArrayUtilities.Fill(Ltt, 0, ASizeExt, 0);
+ end;
+end;
+
+{ TBinPolyX86V128Size1 }
+
+constructor TBinPolyX86V128Size1.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size1.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(1, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size2 }
+
+constructor TBinPolyX86V128Size2.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size2.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(2, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size3 }
+
+constructor TBinPolyX86V128Size3.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size3.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(3, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size4 }
+
+constructor TBinPolyX86V128Size4.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size4.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(4, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size5 }
+
+constructor TBinPolyX86V128Size5.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size5.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(5, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size6 }
+
+constructor TBinPolyX86V128Size6.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size6.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(6, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size7 }
+
+constructor TBinPolyX86V128Size7.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size7.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(7, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size8 }
+
+constructor TBinPolyX86V128Size8.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size8.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(8, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size9 }
+
+constructor TBinPolyX86V128Size9.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size9.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(9, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+{ TBinPolyX86V128Size10 }
+
+constructor TBinPolyX86V128Size10.Create(AN: Int32; const AReduce: IBinPolyReduce);
+begin
+ inherited Create(AN, AReduce);
+end;
+
+procedure TBinPolyX86V128Size10.Multiply(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ MultiplySmallFixed(10, FReduce, FSizeExt, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpBinPolys.pas b/CryptoLib/src/Math/BinPoly/ClpBinPolys.pas
new file mode 100644
index 00000000..6512431d
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpBinPolys.pas
@@ -0,0 +1,311 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBinPolys;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpArrayUtilities,
+ ClpCryptoLibTypes,
+ ClpInt64Utilities,
+ ClpNat,
+ ClpIBinPolyMul,
+ ClpIBinPolyInv,
+ ClpBinPolyMulBaseBinomialReduce,
+ ClpBinPolyMulBaseTrinomialReduce,
+ ClpBinPolyMulBasePentanomialReduce,
+ ClpBinPolyScalarBackend,
+ ClpBinPolyX86V128Backend,
+ ClpItohTsujiiInv;
+
+type
+ ///
+ /// Static entry point for binary-polynomial helpers. Reducer-independent operations
+ /// (Size, Create, Add, AddTo, etc.) sit at the top level;
+ /// factories classified by reduction polynomial shape live under the nested
+ /// TBinPolysMul class, and inversion factories under TBinPolysInv
+ /// (Itoh-Tsujii today).
+ ///
+ ///
+ /// Internal library surface — consumed by the generic F2m field layer and other
+ /// in-library callers, not a published public API.
+ ///
+ TBinPolys = class sealed
+ public
+ ///
+ /// Number of UInt64 limbs required to hold a polynomial of bit length .
+ ///
+ class function Size(AN: Int32): Int32; static;
+ ///
+ /// Allocate a fresh limb array of length (in UInt64 limbs, as
+ /// returned by Size), initialised to zero. Caller-side bit-length-to-limb-count
+ /// conversion sits at Size; this helper takes the already-converted limb count,
+ /// matching the shape of Add / AddTo.
+ ///
+ class function Create(ASize: Int32): TCryptoLibUInt64Array; static;
+ ///
+ /// Compute AZ = AX + AY as polynomial addition over GF(2) (limb-wise XOR).
+ /// Independent of any reduction polynomial: degree-<n stays degree-<n automatically
+ /// (no carry, no reduction). Operates on -limb slices starting at
+ /// the given offsets.
+ ///
+ class procedure Add(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ ///
+ /// Compute AZ = AZ + AX as polynomial addition over GF(2) (limb-wise XOR into the
+ /// accumulator). See Add for the reduction-independence rationale.
+ ///
+ class procedure AddTo(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ ///
+ /// Copy a polynomial: AZ[AzOff..AzOff + ASize] = AX[AxOff..AxOff + ASize].
+ /// No secret-wipe semantics — value-level move.
+ ///
+ class procedure Copy(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ ///
+ /// Set the polynomial to the zero element of the ring: write 0 to every limb in
+ /// AZ[AzOff..AzOff + ASize]. Value-level — for initialising accumulators and
+ /// similar. For wiping secret-bearing intermediate buffers, use Clear instead.
+ ///
+ class procedure Zero(ASize: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ ///
+ /// Secret-wipe: actively erase AZ[AzOff..AzOff + ASize]. Use this — not
+ /// Zero — at sites where the buffer carried partial-product / key material that
+ /// must be wiped under the project's side-channel discipline.
+ ///
+ class procedure Clear(ASize: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ ///
+ /// Set the polynomial to 1 (the multiplicative identity in GF(2)[x] / r(x) for any r(x)
+ /// with a non-zero constant term — true for all binomial / trinomial / pentanomial
+ /// reductions this subsystem supports). This is the polynomial 1 (low bit set, all other
+ /// bits clear), not "all bits set".
+ ///
+ class procedure One(ASize: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32); static;
+ ///
+ /// Constant-time equality test: returns UInt64.MaxValue if
+ /// AX[AxOff..AxOff + ASize] equals AY[AyOff..AyOff + ASize] limb-for-limb,
+ /// and 0 otherwise. Forwards to TNat.EqualTo64; safe to use on
+ /// secret-bearing polynomials.
+ ///
+ class function EqualTo(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32): UInt64; static;
+ ///
+ /// Constant-time test for the multiplicative identity: returns UInt64.MaxValue if
+ /// AX is the polynomial 1 (low bit set, all other bits clear), and 0
+ /// otherwise. Safe to use on secret-bearing polynomials.
+ ///
+ class function EqualToOne(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): UInt64; static;
+ ///
+ /// Constant-time test for the zero element: returns UInt64.MaxValue if every limb
+ /// of AX is zero, and 0 otherwise. Safe to use on secret-bearing
+ /// polynomials.
+ ///
+ class function EqualToZero(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): UInt64; static;
+ ///
+ /// Variable-time bit length of the polynomial in AX: the position of its most
+ /// significant set bit plus one (i.e. degree + 1), or 0 for the zero polynomial. The
+ /// Var suffix flags the data-dependent running time — must not be used where the
+ /// polynomial is secret and timing is observable.
+ ///
+ class function BitLengthVar(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): Int32; static;
+
+ type
+ ///
+ /// Factories for IBinPolyMul instances, classified by reduction polynomial shape:
+ /// Binomial for x^n + 1, Trinomial for x^n + x^k + 1, and
+ /// Pentanomial for x^n + x^k3 + x^k2 + x^k1 + 1.
+ ///
+ ///
+ /// The factories check parameter ranges and tap ordering but not irreducibility; callers
+ /// attest to irreducibility by selecting the appropriate factory (a reducible polynomial
+ /// yields defined-but-meaningless results).
+ ///
+ TBinPolysMul = class sealed
+ strict private
+ ///
+ /// Upper bound on the polynomial bit length n, enforced at factory time. The cap keeps
+ /// all downstream limb-count and offset arithmetic provably within Int32 range.
+ ///
+ const
+ MaxN = 1 shl 20;
+ class function CreateBinPolyMul(AN: Int32; const AReduce: IBinPolyReduce): IBinPolyMul; static;
+ public
+ /// Reduction by x^n + 1 (cyclic ring).
+ class function Binomial(AN: Int32): IBinPolyMul; static;
+ /// Reduction by x^n + x^k + 1.
+ class function Trinomial(AN, AK: Int32): IBinPolyMul; static;
+ /// Reduction by x^n + x^k3 + x^k2 + x^k1 + 1.
+ class function Pentanomial(AN, AK1, AK2, AK3: Int32): IBinPolyMul; static;
+ end;
+
+ ///
+ /// Factories for IBinPolyInv instances (multiplicative inversion in GF(2^n)),
+ /// the inversion-specialised sibling of TBinPolysMul.
+ ///
+ ///
+ /// Inversion requires a field: the reduction polynomial backing the IBinPolyMul
+ /// passed to ItohTsujii must be irreducible. The binomial reducer (x^n + 1)
+ /// is always reducible and must not be passed.
+ ///
+ TBinPolysInv = class sealed
+ public
+ ///
+ /// Itoh-Tsujii inversion driving the supplied IBinPolyMul's arithmetic:
+ /// a^{-1} = a^(2^n - 2) via an addition chain on n - 1. Valid for any
+ /// n (even or odd) provided the reduction polynomial is irreducible.
+ ///
+ class function ItohTsujii(const AMul: IBinPolyMul): IBinPolyInv; static;
+ end;
+ end;
+
+implementation
+
+{ TBinPolys }
+
+class function TBinPolys.Size(AN: Int32): Int32;
+begin
+ Result := (AN + 63) shr 6;
+end;
+
+class function TBinPolys.Create(ASize: Int32): TCryptoLibUInt64Array;
+begin
+ SetLength(Result, ASize);
+end;
+
+class procedure TBinPolys.Add(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ TNat.Xor64(ASize, AX, AXOff, AY, AYOff, AZ, AZOff);
+end;
+
+class procedure TBinPolys.AddTo(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ TNat.XorTo64(ASize, AX, AXOff, AZ, AZOff);
+end;
+
+class procedure TBinPolys.Copy(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ TNat.Copy64(ASize, AX, AXOff, AZ, AZOff);
+end;
+
+class procedure TBinPolys.Zero(ASize: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ TArrayUtilities.Fill(AZ, AZOff, AZOff + ASize, 0);
+end;
+
+class procedure TBinPolys.Clear(ASize: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ TArrayUtilities.Fill(AZ, AZOff, AZOff + ASize, 0);
+end;
+
+class procedure TBinPolys.One(ASize: Int32; const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+begin
+ AZ[AZOff] := 1;
+ if ASize > 1 then
+ TArrayUtilities.Fill(AZ, AZOff + 1, AZOff + ASize, 0);
+end;
+
+class function TBinPolys.EqualTo(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32): UInt64;
+begin
+ Result := TNat.EqualTo64(ASize, AX, AXOff, AY, AYOff);
+end;
+
+class function TBinPolys.EqualToOne(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): UInt64;
+begin
+ Result := TNat.EqualToOne64(ASize, AX, AXOff);
+end;
+
+class function TBinPolys.EqualToZero(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): UInt64;
+begin
+ Result := TNat.EqualToZero64(ASize, AX, AXOff);
+end;
+
+class function TBinPolys.BitLengthVar(ASize: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): Int32;
+var
+ LI: Int32;
+ LX_i: UInt64;
+begin
+ for LI := ASize - 1 downto 0 do
+ begin
+ LX_i := AX[AXOff + LI];
+ if LX_i <> 0 then
+ Exit(LI * TInt64Utilities.NumBits + TInt64Utilities.BitLength(LX_i));
+ end;
+ Result := 0;
+end;
+
+{ TBinPolys.TBinPolysMul }
+
+class function TBinPolys.TBinPolysMul.CreateBinPolyMul(AN: Int32; const AReduce: IBinPolyReduce): IBinPolyMul;
+begin
+ {$IFDEF CRYPTOLIB_X86_SIMD}
+ if TBinPolyX86V128Backend.IsEnabled then
+ Exit(TBinPolyX86V128Backend.CreateBinPolyMul(AN, AReduce));
+ {$ENDIF}
+ Result := TBinPolyScalarBackend.CreateBinPolyMul(AN, AReduce);
+end;
+
+class function TBinPolys.TBinPolysMul.Binomial(AN: Int32): IBinPolyMul;
+begin
+ if AN < 1 then
+ raise EArgumentOutOfRangeException.Create('n must be positive');
+ if AN > MaxN then
+ raise EArgumentOutOfRangeException.Create('n must be at most 2^20');
+ Result := CreateBinPolyMul(AN, TBinPolyMulBaseBinomialReduce.Create(AN));
+end;
+
+class function TBinPolys.TBinPolysMul.Trinomial(AN, AK: Int32): IBinPolyMul;
+begin
+ if AN < 3 then
+ raise EArgumentOutOfRangeException.Create('n must be at least 3');
+ if AN > MaxN then
+ raise EArgumentOutOfRangeException.Create('n must be at most 2^20');
+ if (AK < 1) or (AK >= AN) then
+ raise EArgumentOutOfRangeException.Create('k must satisfy 0 < k < n');
+ Result := CreateBinPolyMul(AN, TBinPolyMulBaseTrinomialReduce.Create(AN, AK));
+end;
+
+class function TBinPolys.TBinPolysMul.Pentanomial(AN, AK1, AK2, AK3: Int32): IBinPolyMul;
+begin
+ if AN < 5 then
+ raise EArgumentOutOfRangeException.Create('n must be at least 5');
+ if AN > MaxN then
+ raise EArgumentOutOfRangeException.Create('n must be at most 2^20');
+ if (AK1 < 1) or (AK2 <= AK1) or (AK3 <= AK2) or (AK3 >= AN) then
+ raise EArgumentException.Create('must satisfy 0 < k1 < k2 < k3 < n');
+ Result := CreateBinPolyMul(AN, TBinPolyMulBasePentanomialReduce.Create(AN, AK1, AK2, AK3));
+end;
+
+{ TBinPolys.TBinPolysInv }
+
+class function TBinPolys.TBinPolysInv.ItohTsujii(const AMul: IBinPolyMul): IBinPolyInv;
+begin
+ if AMul = nil then
+ raise EArgumentNilException.Create('mul');
+ if AMul.N < 2 then
+ raise EArgumentException.Create('inversion requires a field of degree at least 2');
+ Result := TItohTsujiiInv.Create(AMul);
+end;
+
+end.
diff --git a/CryptoLib/src/Math/BinPoly/ClpItohTsujiiInv.pas b/CryptoLib/src/Math/BinPoly/ClpItohTsujiiInv.pas
new file mode 100644
index 00000000..996775fd
--- /dev/null
+++ b/CryptoLib/src/Math/BinPoly/ClpItohTsujiiInv.pas
@@ -0,0 +1,166 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpItohTsujiiInv;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ SysUtils,
+ ClpInt32Utilities,
+ ClpCryptoLibTypes,
+ ClpIBinPolyMul,
+ ClpIBinPolyInv;
+
+type
+ ///
+ /// Itoh-Tsujii multiplicative inversion in GF(2^n): computes
+ /// a^{-1} = a^(2^n - 2) = (a^(2^(n-1) - 1))^2 using a generic binary addition chain
+ /// on the exponent e = n - 1, driving the supplied IBinPolyMul's
+ /// Multiply / Square / SquareN.
+ ///
+ ///
+ ///
+ /// Let a_k = a^(2^k - 1). The chain walks the bits of e = n - 1 from the bit
+ /// below the MSB down to bit 0, applying a "double" step (SquareN then Multiply)
+ /// and an "increment" step (Square then Multiply) when the bit is set.
+ ///
+ ///
+ /// The element value never steers control flow: 0 and 1 are fixed points of the primitives,
+ /// so Invert(0) = 0 and Invert(1) = 1 fall out of the unconditional chain
+ /// with no special case. Correct only for an irreducible reduction polynomial — see
+ /// IBinPolyInv.
+ ///
+ ///
+ TItohTsujiiInv = class sealed(TInterfacedObject, IBinPolyInv)
+ private
+ FMul: IBinPolyMul;
+ FN: Int32;
+ FSize: Int32;
+ {$IFDEF DEBUG}
+ procedure DebugAssertInverse(const Aa: TCryptoLibUInt64Array; AaOff: Int32;
+ const Ab: TCryptoLibUInt64Array);
+ {$ENDIF}
+ public
+ constructor Create(const AMul: IBinPolyMul);
+ function GetN: Int32;
+ function GetSize: Int32;
+ procedure Invert(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+ property N: Int32 read GetN;
+ property Size: Int32 read GetSize;
+ end;
+
+implementation
+
+uses
+ ClpBinPolys;
+
+{ TItohTsujiiInv }
+
+constructor TItohTsujiiInv.Create(const AMul: IBinPolyMul);
+begin
+ inherited Create;
+{$IFDEF DEBUG}
+ System.Assert(AMul.N >= 2);
+{$ENDIF}
+ FMul := AMul;
+ FN := AMul.N;
+ FSize := AMul.Size;
+end;
+
+function TItohTsujiiInv.GetN: Int32;
+begin
+ Result := FN;
+end;
+
+function TItohTsujiiInv.GetSize: Int32;
+begin
+ Result := FSize;
+end;
+
+procedure TItohTsujiiInv.Invert(const AX: TCryptoLibUInt64Array; AXOff: Int32;
+ const AZ: TCryptoLibUInt64Array; AZOff: Int32);
+var
+ Lb: TCryptoLibUInt64Array;
+ Lt: TCryptoLibUInt64Array;
+ Ln: Int32;
+ LSize: Int32;
+ Le: Int32;
+ Lj: Int32;
+ LI: Int32;
+begin
+ Ln := FN;
+ LSize := FSize;
+
+ SetLength(Lb, LSize);
+ SetLength(Lt, LSize);
+ try
+ TBinPolys.Copy(LSize, AX, AXOff, Lb, 0);
+
+ Le := Ln - 1;
+ Lj := 1;
+ for LI := TInt32Utilities.BitLength(Le) - 2 downto 0 do
+ begin
+ FMul.SquareN(Lb, 0, Lj, Lt, 0);
+ FMul.Multiply(Lb, 0, Lt, 0, Lb, 0);
+ Lj := Lj shl 1;
+
+ if (Le and (1 shl LI)) <> 0 then
+ begin
+ FMul.Square(Lb, 0, Lb, 0);
+ FMul.Multiply(Lb, 0, AX, AXOff, Lb, 0);
+ System.Inc(Lj);
+ end;
+ end;
+{$IFDEF DEBUG}
+ System.Assert(Lj = Le);
+ DebugAssertInverse(AX, AXOff, Lb);
+{$ENDIF}
+ FMul.Square(Lb, 0, AZ, AZOff);
+ finally
+ TBinPolys.Clear(LSize, Lb, 0);
+ TBinPolys.Clear(LSize, Lt, 0);
+ end;
+end;
+
+{$IFDEF DEBUG}
+procedure TItohTsujiiInv.DebugAssertInverse(const Aa: TCryptoLibUInt64Array; AaOff: Int32;
+ const Ab: TCryptoLibUInt64Array);
+var
+ LProduct: TCryptoLibUInt64Array;
+ LOk: Boolean;
+begin
+ SetLength(LProduct, FSize);
+ try
+ FMul.Square(Ab, 0, LProduct, 0);
+ FMul.Multiply(LProduct, 0, Aa, AaOff, LProduct, 0);
+
+ if TBinPolys.EqualToZero(FSize, Aa, AaOff) <> 0 then
+ LOk := TBinPolys.EqualToZero(FSize, LProduct, 0) <> 0
+ else
+ LOk := TBinPolys.EqualToOne(FSize, LProduct, 0) <> 0;
+
+ System.Assert(LOk, 'Itoh-Tsujii inverse self-check failed');
+ finally
+ TBinPolys.Clear(FSize, LProduct, 0);
+ end;
+end;
+{$ENDIF}
+
+end.
diff --git a/CryptoLib/src/Math/ClpBigInteger.pas b/CryptoLib/src/Math/ClpBigInteger.pas
index 7101258c..fedb4b44 100644
--- a/CryptoLib/src/Math/ClpBigInteger.pas
+++ b/CryptoLib/src/Math/ClpBigInteger.pas
@@ -281,7 +281,6 @@ TBigInteger = record
/// Computes the Jacobi symbol (a/n) for odd positive n.
///
class function Jacobi(const AA, AN: TBigInteger): Int32; static;
- class procedure Boot; static;
end;
implementation
@@ -292,15 +291,13 @@ implementation
{ TBigInteger }
-class procedure TBigInteger.Boot;
+class constructor TBigInteger.Create;
var
LI, LJ, LProduct: Int32;
LPrimeList: TCryptoLibInt32Array;
LSmallConstant: TBigInteger;
LZeroMagnitude: TCryptoLibUInt32Array;
begin
- TSecureRandom.Boot;
-
LZeroMagnitude := nil;
FZero := TBigInteger.Create(0, LZeroMagnitude, False);
FZero.FNBits := 0;
@@ -422,11 +419,6 @@ class procedure TBigInteger.Boot;
end;
end;
-class constructor TBigInteger.Create;
-begin
- Boot;
-end;
-
class function TBigInteger.PopCount(const AValue: UInt32): Int32;
begin
Result := TBitOperations.PopCount32(AValue);
diff --git a/CryptoLib/src/Math/EC/ClpECCurve.pas b/CryptoLib/src/Math/EC/ClpECCurve.pas
index 2b90f90c..bee9e1f8 100644
--- a/CryptoLib/src/Math/EC/ClpECCurve.pas
+++ b/CryptoLib/src/Math/EC/ClpECCurve.pas
@@ -27,7 +27,10 @@ interface
ClpBigInteger,
ClpIFiniteField,
ClpIECCommon,
- ClpLongArray,
+ ClpIF2mFieldData,
+ ClpF2mFieldData,
+ ClpBinPolys,
+ ClpNat,
ClpECAlgorithms,
ClpFiniteFields,
ClpPrimes,
@@ -231,8 +234,7 @@ TAbstractF2mCurve = class abstract(TECCurve, IECCurve, IAbstractF2mCurve)
TF2mCurve = class sealed(TAbstractF2mCurve, IECCurve, IF2mCurve)
strict protected
- FM, FK1, FK2, FK3: Int32;
- FKs: TCryptoLibInt32Array;
+ FF2mFieldData: IF2mFieldData;
FInfinity: IECPoint;
function CreateDefaultMultiplier: IECMultiplier; override;
strict private
@@ -240,11 +242,13 @@ TF2mCurve = class sealed(TAbstractF2mCurve, IECCurve, IF2mCurve)
TDefaultF2mLookupTable = class sealed(TAbstractECLookupTable, IECLookupTable)
strict private
FOuter: IF2mCurve;
+ FF2mFieldData: IF2mFieldData;
FTable: TCryptoLibUInt64Array;
FSize: Int32;
function CreatePoint(const AX, AY: TCryptoLibUInt64Array): IECPoint;
public
- constructor Create(const AOuter: IF2mCurve; const ATable: TCryptoLibUInt64Array; ASize: Int32);
+ constructor Create(const AOuter: IF2mCurve; const AF2mFieldData: IF2mFieldData;
+ const ATable: TCryptoLibUInt64Array; ASize: Int32);
function GetSize: Int32; override;
function Lookup(AIndex: Int32): IECPoint; override;
function LookupVar(AIndex: Int32): IECPoint; override;
@@ -257,6 +261,8 @@ TDefaultF2mLookupTable = class sealed(TAbstractECLookupTable, IECLookupTable)
constructor Create(AM, AK1, AK2, AK3: Int32; const AA, AB, AOrder, ACofactor: TBigInteger); overload;
constructor Create(AM, AK1, AK2, AK3: Int32; const AA, AB: IECFieldElement;
const AOrder, ACofactor: TBigInteger); overload;
+ constructor Create(const AF2mFieldData: IF2mFieldData; const AA, AB: IECFieldElement;
+ const AOrder, ACofactor: TBigInteger); overload;
function CloneCurve: IECCurve; override;
function GetFieldSize: Int32; override;
function GetInfinity: IECPoint; override;
@@ -348,10 +354,12 @@ function TECCurve.TDefaultLookupTable.CreatePoint(const AX, AY: TCryptoLibByteAr
{ TF2mCurve.TDefaultF2mLookupTable }
-constructor TF2mCurve.TDefaultF2mLookupTable.Create(const AOuter: IF2mCurve; const ATable: TCryptoLibUInt64Array; ASize: Int32);
+constructor TF2mCurve.TDefaultF2mLookupTable.Create(const AOuter: IF2mCurve; const AF2mFieldData: IF2mFieldData;
+ const ATable: TCryptoLibUInt64Array; ASize: Int32);
begin
Inherited Create();
FOuter := AOuter;
+ FF2mFieldData := AF2mFieldData;
FTable := ATable;
FSize := ASize;
end;
@@ -367,7 +375,7 @@ function TF2mCurve.TDefaultF2mLookupTable.Lookup(AIndex: Int32): IECPoint;
LMask: UInt64;
LX, LY: TCryptoLibUInt64Array;
begin
- LFeLongs := (FOuter.M + 63) div 64;
+ LFeLongs := TBinPolys.Size(FOuter.M);
System.SetLength(LX, LFeLongs);
System.SetLength(LY, LFeLongs);
LPos := 0;
@@ -393,7 +401,7 @@ function TF2mCurve.TDefaultF2mLookupTable.LookupVar(AIndex: Int32): IECPoint;
LFeLongs, LPos, LJ: Int32;
LX, LY: TCryptoLibUInt64Array;
begin
- LFeLongs := (FOuter.M + 63) div 64;
+ LFeLongs := TBinPolys.Size(FOuter.M);
System.SetLength(LX, LFeLongs);
System.SetLength(LY, LFeLongs);
LPos := AIndex * LFeLongs * 2;
@@ -409,15 +417,10 @@ function TF2mCurve.TDefaultF2mLookupTable.LookupVar(AIndex: Int32): IECPoint;
function TF2mCurve.TDefaultF2mLookupTable.CreatePoint(const AX, AY: TCryptoLibUInt64Array): IECPoint;
var
- LKs: TCryptoLibInt32Array;
LXfe, LYfe: IECFieldElement;
begin
- if FOuter.IsTrinomial then
- LKs := TCryptoLibInt32Array.Create(FOuter.K1)
- else
- LKs := TCryptoLibInt32Array.Create(FOuter.K1, FOuter.K2, FOuter.K3);
- LXfe := TF2mFieldElement.Create(FOuter.M, LKs, TLongArray.Create(AX));
- LYfe := TF2mFieldElement.Create(FOuter.M, LKs, TLongArray.Create(AY));
+ LXfe := TF2mFieldElement.Create(FF2mFieldData, AX);
+ LYfe := TF2mFieldElement.Create(FF2mFieldData, AY);
Result := FOuter.CreateRawPoint(LXfe, LYfe);
end;
@@ -1274,8 +1277,15 @@ function TAbstractF2mCurve.SolveQuadraticEquation(const ABeta: IECFieldElement):
end;
class function TAbstractF2mCurve.Inverse(AM: Int32; const AKs: TCryptoLibInt32Array; const AX: TBigInteger): TBigInteger;
+var
+ LT: TCryptoLibUInt64Array;
+ LF2mFieldData: IF2mFieldData;
+ LFe: IECFieldElement;
begin
- Result := TLongArray.Create(AX).ModInverse(AM, AKs).ToBigInteger();
+ LT := TNat.FromBigInteger64(AM, AX);
+ LF2mFieldData := TF2mFieldData.From(AM, AKs);
+ LFe := TF2mFieldElement.Create(LF2mFieldData, LT);
+ Result := LFe.Invert().ToBigInteger();
end;
function TAbstractF2mCurve.GetIsKoblitz: Boolean;
@@ -1299,14 +1309,7 @@ constructor TF2mCurve.Create(AM, AK: Int32; const AA, AB, AOrder, ACofactor: TBi
constructor TF2mCurve.Create(AM, AK1, AK2, AK3: Int32; const AA, AB, AOrder, ACofactor: TBigInteger);
begin
inherited Create(AM, AK1, AK2, AK3);
- FM := AM;
- FK1 := AK1;
- FK2 := AK2;
- FK3 := AK3;
- if (AK2 or AK3) = 0 then
- FKs := TCryptoLibInt32Array.Create(AK1)
- else
- FKs := TCryptoLibInt32Array.Create(AK1, AK2, AK3);
+ FF2mFieldData := TF2mFieldData.From(AM, AK1, AK2, AK3);
FOrder := AOrder;
FCofactor := ACofactor;
FInfinity := TF2mPoint.Create(Self as IECCurve, nil, nil);
@@ -1319,14 +1322,20 @@ constructor TF2mCurve.Create(AM, AK1, AK2, AK3: Int32; const AA, AB: IECFieldEle
const AOrder, ACofactor: TBigInteger);
begin
inherited Create(AM, AK1, AK2, AK3);
- FM := AM;
- FK1 := AK1;
- FK2 := AK2;
- FK3 := AK3;
- if (AK2 or AK3) = 0 then
- FKs := TCryptoLibInt32Array.Create(AK1)
- else
- FKs := TCryptoLibInt32Array.Create(AK1, AK2, AK3);
+ FF2mFieldData := TF2mFieldData.From(AM, AK1, AK2, AK3);
+ FOrder := AOrder;
+ FCofactor := ACofactor;
+ FInfinity := TF2mPoint.Create(Self as IECCurve, nil, nil);
+ FA := AA;
+ FB := AB;
+ FCoord := F2M_DEFAULT_COORDS;
+end;
+
+constructor TF2mCurve.Create(const AF2mFieldData: IF2mFieldData; const AA, AB: IECFieldElement;
+ const AOrder, ACofactor: TBigInteger);
+begin
+ inherited Create(AF2mFieldData.M, AF2mFieldData.K1, AF2mFieldData.K2, AF2mFieldData.K3);
+ FF2mFieldData := AF2mFieldData;
FOrder := AOrder;
FCofactor := ACofactor;
FInfinity := TF2mPoint.Create(Self as IECCurve, nil, nil);
@@ -1337,12 +1346,12 @@ constructor TF2mCurve.Create(AM, AK1, AK2, AK3: Int32; const AA, AB: IECFieldEle
function TF2mCurve.CloneCurve: IECCurve;
begin
- Result := TF2mCurve.Create(FM, FK1, FK2, FK3, FA, FB, FOrder, FCofactor);
+ Result := TF2mCurve.Create(FF2mFieldData, FA, FB, FOrder, FCofactor);
end;
function TF2mCurve.GetFieldSize: Int32;
begin
- Result := FM;
+ Result := FF2mFieldData.M;
end;
function TF2mCurve.GetInfinity: IECPoint;
@@ -1352,13 +1361,13 @@ function TF2mCurve.GetInfinity: IECPoint;
function TF2mCurve.FromBigInteger(const AX: TBigInteger): IECFieldElement;
var
- LX: TLongArray;
+ LT: TCryptoLibUInt64Array;
begin
- if (not AX.IsInitialized) or (AX.SignValue < 0) or (AX.BitLength > FM) then
+ if (not AX.IsInitialized) or (AX.SignValue < 0) or (AX.BitLength > FF2mFieldData.M) then
raise EArgumentCryptoLibException.Create('value invalid for F2m field element');
- LX := TLongArray.Create(AX);
- Result := TF2mFieldElement.Create(FM, FKs, LX);
+ LT := TNat.FromBigInteger64(FF2mFieldData.M, AX);
+ Result := TF2mFieldElement.Create(FF2mFieldData, LT);
end;
function TF2mCurve.CreateRawPoint(const AX: IECFieldElement; const AY: IECFieldElement): IECPoint;
@@ -1391,27 +1400,27 @@ function TF2mCurve.CreateDefaultMultiplier: IECMultiplier;
function TF2mCurve.IsTrinomial: Boolean;
begin
- Result := (FK2 = 0) and (FK3 = 0);
+ Result := (FF2mFieldData.K2 = 0) and (FF2mFieldData.K3 = 0);
end;
function TF2mCurve.GetM: Int32;
begin
- Result := FM;
+ Result := FF2mFieldData.M;
end;
function TF2mCurve.GetK1: Int32;
begin
- Result := FK1;
+ Result := FF2mFieldData.K1;
end;
function TF2mCurve.GetK2: Int32;
begin
- Result := FK2;
+ Result := FF2mFieldData.K2;
end;
function TF2mCurve.GetK3: Int32;
begin
- Result := FK3;
+ Result := FF2mFieldData.K3;
end;
function TF2mCurve.CreateCacheSafeLookupTable(const APoints: TCryptoLibGenericArray;
@@ -1420,19 +1429,22 @@ function TF2mCurve.CreateCacheSafeLookupTable(const APoints: TCryptoLibGenericAr
LFeLongs, LPos, LI: Int32;
LTable: TCryptoLibUInt64Array;
LP: IECPoint;
+ LX, LY: TCryptoLibUInt64Array;
begin
- LFeLongs := (FM + 63) div 64;
+ LFeLongs := TBinPolys.Size(FF2mFieldData.M);
System.SetLength(LTable, ALen * LFeLongs * 2);
LPos := 0;
for LI := 0 to ALen - 1 do
begin
LP := APoints[AOff + LI];
- (LP.RawXCoord as IF2mFieldElement).X.CopyTo(LTable, LPos);
+ LX := (LP.RawXCoord as IF2mFieldElement).X;
+ LY := (LP.RawYCoord as IF2mFieldElement).X;
+ TBinPolys.Copy(LFeLongs, LX, 0, LTable, LPos);
Inc(LPos, LFeLongs);
- (LP.RawYCoord as IF2mFieldElement).X.CopyTo(LTable, LPos);
+ TBinPolys.Copy(LFeLongs, LY, 0, LTable, LPos);
Inc(LPos, LFeLongs);
end;
- Result := TDefaultF2mLookupTable.Create(Self, LTable, ALen);
+ Result := TDefaultF2mLookupTable.Create(Self as IF2mCurve, FF2mFieldData, LTable, ALen);
end;
end.
diff --git a/CryptoLib/src/Math/EC/ClpECFieldElement.pas b/CryptoLib/src/Math/EC/ClpECFieldElement.pas
index 4bbea10a..a175ff9b 100644
--- a/CryptoLib/src/Math/EC/ClpECFieldElement.pas
+++ b/CryptoLib/src/Math/EC/ClpECFieldElement.pas
@@ -25,7 +25,10 @@ interface
ClpBigInteger,
ClpBigIntegerUtilities,
ClpIECFieldElement,
- ClpLongArray,
+ ClpIF2mFieldData,
+ ClpF2mFieldData,
+ ClpBinPolys,
+ ClpNat,
ClpBitOperations,
ClpInt32Utilities,
ClpArrayUtilities,
@@ -33,7 +36,6 @@ interface
resourcestring
SF2mFieldElementsNotBothInstances = 'Field elements are not both instances of F2mFieldElement';
- SF2mFieldElementIncorrectRepresentation = 'One of the F2m field elements has incorrect representation';
SF2mFieldElementsNotSameField = 'Field elements are not elements of the same field F2m';
SHalfTraceOnlyDefinedForOddM = 'Half-trace only defined for odd m';
SInternalErrorInTraceCalculation = 'Internal error in trace calculation';
@@ -139,14 +141,12 @@ TF2mFieldElement = class sealed(TAbstractF2mFieldElement, IECFieldElement, IAb
Tpb = 2;
Ppb = 3;
strict private
- FRepresentation: Int32;
- FM: Int32;
- FKs: TCryptoLibInt32Array;
- FX: TLongArray;
+ FF2mFieldData: IF2mFieldData;
+ FX: TCryptoLibUInt64Array;
public
class procedure CheckFieldElements(const AA, AB: IECFieldElement); static;
- constructor Create(AM: Int32; const AKs: TCryptoLibInt32Array; const AX: TLongArray);
+ constructor Create(const AF2mFieldData: IF2mFieldData; const AX: TCryptoLibUInt64Array);
function GetBitLength: Int32; override;
function GetIsOne: Boolean; override;
@@ -161,12 +161,10 @@ TF2mFieldElement = class sealed(TAbstractF2mFieldElement, IECFieldElement, IAb
function Subtract(const AB: IECFieldElement): IECFieldElement; override;
function Multiply(const AB: IECFieldElement): IECFieldElement; override;
function MultiplyMinusProduct(const AB, AX, AY: IECFieldElement): IECFieldElement; override;
- function MultiplyPlusProduct(const AB, AX, AY: IECFieldElement): IECFieldElement; override;
function Divide(const AB: IECFieldElement): IECFieldElement; override;
function Negate: IECFieldElement; override;
function Square: IECFieldElement; override;
function SquareMinusProduct(const AX, AY: IECFieldElement): IECFieldElement; override;
- function SquarePlusProduct(const AX, AY: IECFieldElement): IECFieldElement; override;
function SquarePow(APow: Int32): IECFieldElement; override;
function Invert: IECFieldElement; override;
function Sqrt: IECFieldElement; override;
@@ -179,14 +177,16 @@ TF2mFieldElement = class sealed(TAbstractF2mFieldElement, IECFieldElement, IAb
function GetK1: Int32;
function GetK2: Int32;
function GetK3: Int32;
- function GetX: TLongArray;
+ function GetX: TCryptoLibUInt64Array;
+ function GetF2mFieldData: IF2mFieldData;
property Representation: Int32 read GetRepresentation;
property M: Int32 read GetM;
property K1: Int32 read GetK1;
property K2: Int32 read GetK2;
property K3: Int32 read GetK3;
- property X: TLongArray read GetX;
+ property X: TCryptoLibUInt64Array read GetX;
+ property F2mFieldData: IF2mFieldData read GetF2mFieldData;
end;
implementation
@@ -740,47 +740,49 @@ class procedure TF2mFieldElement.CheckFieldElements(const AA, AB: IECFieldElemen
begin
if not Supports(AA, IF2mFieldElement, LAIntf) or not Supports(AB, IF2mFieldElement, LBIntf) then
raise EArgumentCryptoLibException.Create(SF2mFieldElementsNotBothInstances);
- if LAIntf.Representation <> LBIntf.Representation then
- raise EArgumentCryptoLibException.Create(SF2mFieldElementIncorrectRepresentation);
- if (LAIntf.M <> LBIntf.M) or (LAIntf.K1 <> LBIntf.K1) or (LAIntf.K2 <> LBIntf.K2) or (LAIntf.K3 <> LBIntf.K3) then
+ if not TF2mFieldData.Equals(LAIntf.F2mFieldData, LBIntf.F2mFieldData) then
raise EArgumentCryptoLibException.Create(SF2mFieldElementsNotSameField);
end;
-constructor TF2mFieldElement.Create(AM: Int32; const AKs: TCryptoLibInt32Array; const AX: TLongArray);
+constructor TF2mFieldElement.Create(const AF2mFieldData: IF2mFieldData; const AX: TCryptoLibUInt64Array);
begin
- Inherited Create;
- FM := AM;
- if System.Length(AKs) = 1 then
- FRepresentation := Tpb
- else
- FRepresentation := Ppb;
- FKs := AKs;
+ inherited Create;
+ if AF2mFieldData = nil then
+ raise EArgumentNilCryptoLibException.Create('f2mFieldData');
+ if AX = nil then
+ raise EArgumentNilCryptoLibException.Create('x');
+ FF2mFieldData := AF2mFieldData;
FX := AX;
end;
-function TF2mFieldElement.GetX: TLongArray;
+function TF2mFieldElement.GetF2mFieldData: IF2mFieldData;
+begin
+ Result := FF2mFieldData;
+end;
+
+function TF2mFieldElement.GetX: TCryptoLibUInt64Array;
begin
Result := FX;
end;
function TF2mFieldElement.GetBitLength: Int32;
begin
- Result := FX.Degree();
+ Result := TBinPolys.BitLengthVar(System.Length(FX), FX, 0);
end;
function TF2mFieldElement.GetIsOne: Boolean;
begin
- Result := FX.IsOne();
+ Result := TBinPolys.EqualToOne(System.Length(FX), FX, 0) <> 0;
end;
function TF2mFieldElement.GetIsZero: Boolean;
begin
- Result := FX.IsZero();
+ Result := TBinPolys.EqualToZero(System.Length(FX), FX, 0) <> 0;
end;
function TF2mFieldElement.TestBitZero: Boolean;
begin
- Result := FX.TestBitZero();
+ Result := (FX[0] and 1) <> 0;
end;
function TF2mFieldElement.GetFieldName: String;
@@ -790,29 +792,40 @@ function TF2mFieldElement.GetFieldName: String;
function TF2mFieldElement.GetFieldSize: Int32;
begin
- Result := FM;
+ Result := FF2mFieldData.M;
end;
function TF2mFieldElement.ToBigInteger: TBigInteger;
begin
- Result := FX.ToBigInteger();
+ Result := TNat.ToBigInteger64(System.Length(FX), FX);
end;
function TF2mFieldElement.Add(const AB: IECFieldElement): IECFieldElement;
var
- LIarrClone: TLongArray;
LBIntf: IF2mFieldElement;
+ LSize: Int32;
+ LBx: TCryptoLibUInt64Array;
+ LZ: TCryptoLibUInt64Array;
begin
if not Supports(AB, IF2mFieldElement, LBIntf) then
raise EArgumentCryptoLibException.Create(SF2mFieldElementsNotBothInstances);
- LIarrClone := FX.Copy();
- LIarrClone.AddShiftedByWords(LBIntf.X, 0);
- Result := TF2mFieldElement.Create(FM, FKs, LIarrClone);
+ LSize := System.Length(FX);
+ LBx := LBIntf.X;
+ LZ := TBinPolys.Create(LSize);
+ TBinPolys.Add(LSize, FX, 0, LBx, 0, LZ, 0);
+ Result := TF2mFieldElement.Create(FF2mFieldData, LZ);
end;
function TF2mFieldElement.AddOne: IECFieldElement;
+var
+ LSize: Int32;
+ LZ: TCryptoLibUInt64Array;
begin
- Result := TF2mFieldElement.Create(FM, FKs, FX.AddOne());
+ LSize := System.Length(FX);
+ LZ := TBinPolys.Create(LSize);
+ TBinPolys.Copy(LSize, FX, 0, LZ, 0);
+ LZ[0] := LZ[0] xor 1;
+ Result := TF2mFieldElement.Create(FF2mFieldData, LZ);
end;
function TF2mFieldElement.Subtract(const AB: IECFieldElement): IECFieldElement;
@@ -823,10 +836,17 @@ function TF2mFieldElement.Subtract(const AB: IECFieldElement): IECFieldElement;
function TF2mFieldElement.Multiply(const AB: IECFieldElement): IECFieldElement;
var
LBIntf: IF2mFieldElement;
+ LSize: Int32;
+ LBx: TCryptoLibUInt64Array;
+ LZ: TCryptoLibUInt64Array;
begin
if not Supports(AB, IF2mFieldElement, LBIntf) then
raise EArgumentCryptoLibException.Create(SF2mFieldElementsNotBothInstances);
- Result := TF2mFieldElement.Create(FM, FKs, FX.ModMultiply(LBIntf.X, FM, FKs));
+ LSize := System.Length(FX);
+ LBx := LBIntf.X;
+ LZ := TBinPolys.Create(LSize);
+ FF2mFieldData.Mul.Multiply(FX, 0, LBx, 0, LZ, 0);
+ Result := TF2mFieldElement.Create(FF2mFieldData, LZ);
end;
function TF2mFieldElement.MultiplyMinusProduct(const AB, AX, AY: IECFieldElement): IECFieldElement;
@@ -834,27 +854,6 @@ function TF2mFieldElement.MultiplyMinusProduct(const AB, AX, AY: IECFieldElement
Result := MultiplyPlusProduct(AB, AX, AY);
end;
-function TF2mFieldElement.MultiplyPlusProduct(const AB, AX, AY: IECFieldElement): IECFieldElement;
-var
- LAx, LBx, LXx, LYx: TLongArray;
- LAb, LXy: TLongArray;
- LBIntf, LXIntf, LYIntf: IF2mFieldElement;
-begin
- if not Supports(AB, IF2mFieldElement, LBIntf) or not Supports(AX, IF2mFieldElement, LXIntf) or not Supports(AY, IF2mFieldElement, LYIntf) then
- raise EArgumentCryptoLibException.Create(SF2mFieldElementsNotBothInstances);
- LAx := FX;
- LBx := LBIntf.X;
- LXx := LXIntf.X;
- LYx := LYIntf.X;
- LAb := LAx.Multiply(LBx, FM, FKs);
- LXy := LXx.Multiply(LYx, FM, FKs);
- if TLongArray.AreAliased(LAb, LAx) or TLongArray.AreAliased(LAb, LBx) then
- LAb := LAb.Copy();
- LAb.AddShiftedByWords(LXy, 0);
- LAb.Reduce(FM, FKs);
- Result := TF2mFieldElement.Create(FM, FKs, LAb);
-end;
-
function TF2mFieldElement.Divide(const AB: IECFieldElement): IECFieldElement;
var
LBInv: IECFieldElement;
@@ -869,8 +868,14 @@ function TF2mFieldElement.Negate: IECFieldElement;
end;
function TF2mFieldElement.Square: IECFieldElement;
+var
+ LSize: Int32;
+ LZ: TCryptoLibUInt64Array;
begin
- Result := TF2mFieldElement.Create(FM, FKs, FX.ModSquare(FM, FKs));
+ LSize := System.Length(FX);
+ LZ := TBinPolys.Create(LSize);
+ FF2mFieldData.Mul.Square(FX, 0, LZ, 0);
+ Result := TF2mFieldElement.Create(FF2mFieldData, LZ);
end;
function TF2mFieldElement.SquareMinusProduct(const AX, AY: IECFieldElement): IECFieldElement;
@@ -878,50 +883,50 @@ function TF2mFieldElement.SquareMinusProduct(const AX, AY: IECFieldElement): IEC
Result := SquarePlusProduct(AX, AY);
end;
-function TF2mFieldElement.SquarePlusProduct(const AX, AY: IECFieldElement): IECFieldElement;
-var
- LAx, LXx, LYx: TLongArray;
- LAA, LXy: TLongArray;
- LXIntf, LYIntf: IF2mFieldElement;
-begin
- if not Supports(AX, IF2mFieldElement, LXIntf) or not Supports(AY, IF2mFieldElement, LYIntf) then
- raise EArgumentCryptoLibException.Create(SF2mFieldElementsNotBothInstances);
- LAx := FX;
- LXx := LXIntf.X;
- LYx := LYIntf.X;
- LAA := LAx.Square(FM, FKs);
- LXy := LXx.Multiply(LYx, FM, FKs);
- if TLongArray.AreAliased(LAA, LAx) then
- LAA := LAA.Copy();
- LAA.AddShiftedByWords(LXy, 0);
- LAA.Reduce(FM, FKs);
- Result := TF2mFieldElement.Create(FM, FKs, LAA);
-end;
-
function TF2mFieldElement.SquarePow(APow: Int32): IECFieldElement;
+var
+ LSize: Int32;
+ LZ: TCryptoLibUInt64Array;
begin
if APow < 1 then
Result := Self as IECFieldElement
else
- Result := TF2mFieldElement.Create(FM, FKs, FX.ModSquareN(APow, FM, FKs));
+ begin
+ LSize := System.Length(FX);
+ LZ := TBinPolys.Create(LSize);
+ FF2mFieldData.Mul.SquareN(FX, 0, APow, LZ, 0);
+ Result := TF2mFieldElement.Create(FF2mFieldData, LZ);
+ end;
end;
function TF2mFieldElement.Invert: IECFieldElement;
+var
+ LSize: Int32;
+ LZ: TCryptoLibUInt64Array;
begin
- Result := TF2mFieldElement.Create(FM, FKs, FX.ModInverse(FM, FKs));
+ if GetBitLength() <= 1 then
+ Result := Self as IECFieldElement
+ else
+ begin
+ LSize := System.Length(FX);
+ LZ := TBinPolys.Create(LSize);
+ FF2mFieldData.Inv.Invert(FX, 0, LZ, 0);
+ Result := TF2mFieldElement.Create(FF2mFieldData, LZ);
+ end;
end;
function TF2mFieldElement.Sqrt: IECFieldElement;
begin
- if FX.IsZero() or FX.IsOne() then
+ if GetIsZero or GetIsOne then
Result := Self as IECFieldElement
else
- Result := SquarePow(FM - 1);
+ Result := SquarePow(FF2mFieldData.M - 1);
end;
function TF2mFieldElement.Equals(const AOther: IECFieldElement): Boolean;
var
LOtherF2m: IF2mFieldElement;
+ LOtherX: TCryptoLibUInt64Array;
begin
if AOther = nil then
Exit(False);
@@ -929,45 +934,43 @@ function TF2mFieldElement.Equals(const AOther: IECFieldElement): Boolean;
Exit(True);
if not Supports(AOther, IF2mFieldElement, LOtherF2m) then
Exit(False);
- Result := (FM = LOtherF2m.M) and (FRepresentation = LOtherF2m.Representation)
- and (GetK1 = LOtherF2m.K1) and (GetK2 = LOtherF2m.K2) and (GetK3 = LOtherF2m.K3)
- and FX.Equals(LOtherF2m.X);
+ LOtherX := LOtherF2m.X;
+ Result := TF2mFieldData.Equals(FF2mFieldData, LOtherF2m.F2mFieldData)
+ and (System.Length(FX) = System.Length(LOtherX))
+ and (TBinPolys.EqualTo(System.Length(FX), FX, 0, LOtherX, 0) <> 0);
end;
function TF2mFieldElement.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt; {$ENDIF DELPHI}
begin
- Result := FX.GetHashCode() xor FM xor TArrayUtilities.GetArrayHashCode(FKs);
+ Result := TArrayUtilities.GetArrayHashCode(FX, 0, System.Length(FX)) xor TF2mFieldData.GetHashCode(FF2mFieldData);
end;
function TF2mFieldElement.GetRepresentation: Int32;
begin
- Result := FRepresentation;
+ if System.Length(FF2mFieldData.Ks) = 1 then
+ Result := Tpb
+ else
+ Result := Ppb;
end;
function TF2mFieldElement.GetM: Int32;
begin
- Result := FM;
+ Result := FF2mFieldData.M;
end;
function TF2mFieldElement.GetK1: Int32;
begin
- Result := FKs[0];
+ Result := FF2mFieldData.K1;
end;
function TF2mFieldElement.GetK2: Int32;
begin
- if System.Length(FKs) >= 2 then
- Result := FKs[1]
- else
- Result := 0;
+ Result := FF2mFieldData.K2;
end;
function TF2mFieldElement.GetK3: Int32;
begin
- if System.Length(FKs) >= 3 then
- Result := FKs[2]
- else
- Result := 0;
+ Result := FF2mFieldData.K3;
end;
end.
diff --git a/CryptoLib/src/Math/EC/ClpF2mFieldData.pas b/CryptoLib/src/Math/EC/ClpF2mFieldData.pas
new file mode 100644
index 00000000..a2ac8fe5
--- /dev/null
+++ b/CryptoLib/src/Math/EC/ClpF2mFieldData.pas
@@ -0,0 +1,151 @@
+{ *********************************************************************************** }
+{ * CryptoLib Library * }
+{ * Author - Ugochukwu Mmaduekwe * }
+{ * Github Repository * }
+{ * * }
+{ * 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 * }
+{ * the development of this library * }
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpF2mFieldData;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+ ClpCryptoLibTypes,
+ ClpArrayUtilities,
+ ClpIBinPolyMul,
+ ClpIBinPolyInv,
+ ClpIF2mFieldData;
+
+type
+ ///
+ /// Field metadata and binary-polynomial arithmetic primitives for GF(2^m).
+ ///
+ TF2mFieldData = class sealed(TInterfacedObject, IF2mFieldData)
+ strict private
+ FM: Int32;
+ FKs: TCryptoLibInt32Array;
+ FMul: IBinPolyMul;
+ FInv: IBinPolyInv;
+ function GetM: Int32;
+ function GetKs: TCryptoLibInt32Array;
+ function GetMul: IBinPolyMul;
+ function GetInv: IBinPolyInv;
+ public
+ constructor Create(AM: Int32; const AKs: TCryptoLibInt32Array; const AMul: IBinPolyMul;
+ const AInv: IBinPolyInv);
+ class function From(AM, AK1, AK2, AK3: Int32): IF2mFieldData; overload; static;
+ class function From(AM: Int32; const AKs: TCryptoLibInt32Array): IF2mFieldData; overload; static;
+ function GetK1: Int32;
+ function GetK2: Int32;
+ function GetK3: Int32;
+ class function Equals(const A, B: IF2mFieldData): Boolean; static;
+ class function GetHashCode(const AData: IF2mFieldData): Int32; static;
+ end;
+
+implementation
+
+uses
+ ClpBinPolys;
+
+{ TF2mFieldData }
+
+constructor TF2mFieldData.Create(AM: Int32; const AKs: TCryptoLibInt32Array; const AMul: IBinPolyMul;
+ const AInv: IBinPolyInv);
+begin
+ inherited Create;
+ FM := AM;
+ FKs := AKs;
+ FMul := AMul;
+ FInv := AInv;
+end;
+
+function TF2mFieldData.GetM: Int32;
+begin
+ Result := FM;
+end;
+
+function TF2mFieldData.GetKs: TCryptoLibInt32Array;
+begin
+ Result := FKs;
+end;
+
+function TF2mFieldData.GetMul: IBinPolyMul;
+begin
+ Result := FMul;
+end;
+
+function TF2mFieldData.GetInv: IBinPolyInv;
+begin
+ Result := FInv;
+end;
+
+class function TF2mFieldData.From(AM, AK1, AK2, AK3: Int32): IF2mFieldData;
+begin
+ if AK2 = 0 then
+ Result := From(AM, TCryptoLibInt32Array.Create(AK1))
+ else
+ Result := From(AM, TCryptoLibInt32Array.Create(AK1, AK2, AK3));
+end;
+
+class function TF2mFieldData.From(AM: Int32; const AKs: TCryptoLibInt32Array): IF2mFieldData;
+var
+ LMul: IBinPolyMul;
+ LInv: IBinPolyInv;
+begin
+ if System.Length(AKs) = 1 then
+ LMul := TBinPolys.TBinPolysMul.Trinomial(AM, AKs[0])
+ else
+ LMul := TBinPolys.TBinPolysMul.Pentanomial(AM, AKs[0], AKs[1], AKs[2]);
+ LInv := TBinPolys.TBinPolysInv.ItohTsujii(LMul);
+ Result := TF2mFieldData.Create(AM, AKs, LMul, LInv);
+end;
+
+function TF2mFieldData.GetK1: Int32;
+begin
+ Result := FKs[0];
+end;
+
+function TF2mFieldData.GetK2: Int32;
+begin
+ if System.Length(FKs) >= 2 then
+ Result := FKs[1]
+ else
+ Result := 0;
+end;
+
+function TF2mFieldData.GetK3: Int32;
+begin
+ if System.Length(FKs) >= 3 then
+ Result := FKs[2]
+ else
+ Result := 0;
+end;
+
+class function TF2mFieldData.Equals(const A, B: IF2mFieldData): Boolean;
+begin
+ if A = B then
+ Exit(True);
+ if (A = nil) or (B = nil) then
+ Exit(False);
+ Result := (A.M = B.M) and TArrayUtilities.AreEqual(A.Ks, B.Ks);
+end;
+
+class function TF2mFieldData.GetHashCode(const AData: IF2mFieldData): Int32;
+begin
+ if AData = nil then
+ Exit(0);
+ Result := AData.M xor TArrayUtilities.GetArrayHashCode(AData.Ks);
+end;
+
+end.
diff --git a/CryptoLib/src/Math/EC/ClpLongArray.pas b/CryptoLib/src/Math/EC/ClpLongArray.pas
deleted file mode 100644
index 2cefd94a..00000000
--- a/CryptoLib/src/Math/EC/ClpLongArray.pas
+++ /dev/null
@@ -1,1241 +0,0 @@
-{ *********************************************************************************** }
-{ * CryptoLib Library * }
-{ * Author - Ugochukwu Mmaduekwe * }
-{ * Github Repository * }
-{ * * }
-{ * 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 * }
-{ * the development of this library * }
-{ * ******************************************************************************* * }
-
-(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
-
-unit ClpLongArray;
-
-{$I ..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
- SysUtils,
- Math,
- ClpCryptoLibTypes,
- ClpBitOperations,
- ClpInt64Utilities,
- ClpNat,
- ClpInterleave,
- ClpArrayUtilities,
- ClpBigInteger,
- ClpBigIntegerUtilities;
-
-resourcestring
- SInvalidF2mFieldValue = 'invalid F2m field value';
-
-type
- TLongArray = record
- private
- FData: TCryptoLibUInt64Array;
-
- class function BitLength(AW: UInt64): Int32; overload; static;
- class function ShiftUp(const AX: TCryptoLibUInt64Array; AXOff, ACount, AShift: Int32): UInt64; overload; static;
- class function ShiftUp(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff, ACount, AShift: Int32): UInt64; overload; static;
- class function AddShiftedUp(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, ACount, AShift: Int32): UInt64; static;
- class function AddShiftedDown(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, ACount, AShift: Int32): UInt64; static;
- class procedure Add(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, ACount: Int32); overload; static;
- class procedure Add(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff, ACount: Int32); overload; static;
- class procedure AddBoth(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY1: TCryptoLibUInt64Array; AY1Off: Int32; const AY2: TCryptoLibUInt64Array; AY2Off, ACount: Int32); static;
- class procedure FlipWord(ABuf: TCryptoLibUInt64Array; AOff, ABit: Int32; AWord: UInt64); static;
- class function TestBit(const ABuf: TCryptoLibUInt64Array; AOff, AN: Int32): Boolean; static;
- class procedure FlipBit(ABuf: TCryptoLibUInt64Array; AOff, AN: Int32); static;
- class procedure MultiplyWord(AA: UInt64; const AB: TCryptoLibUInt64Array; ABLen: Int32; AC: TCryptoLibUInt64Array; ACOff: Int32); static;
- function DegreeFrom(ALimit: Int32): Int32;
- function ResizedData(ANewLen: Int32): TCryptoLibUInt64Array;
- procedure AddShiftedByBitsSafe(const AOther: TLongArray; AOtherDegree, ABits: Int32);
- class function ReduceResult(const ABuf: TCryptoLibUInt64Array; AOff, ALen, AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray; static;
- class function ReduceInPlace(ABuf: TCryptoLibUInt64Array; AOff, ALen, AM: Int32; const AKs: TCryptoLibInt32Array): Int32; static;
- class procedure ReduceBitWise(ABuf: TCryptoLibUInt64Array; AOff, ABitLength, AM: Int32; const AKs: TCryptoLibInt32Array); static;
- class procedure ReduceBit(ABuf: TCryptoLibUInt64Array; AOff, ABit, AM: Int32; const AKs: TCryptoLibInt32Array); static;
- class procedure ReduceWordWise(ABuf: TCryptoLibUInt64Array; AOff, ALen, AToBit, AM: Int32; const AKs: TCryptoLibInt32Array); static;
- class procedure ReduceWord(ABuf: TCryptoLibUInt64Array; AOff, ABit: Int32; AWord: UInt64; AM: Int32; const AKs: TCryptoLibInt32Array); static;
- class procedure ReduceVectorWise(ABuf: TCryptoLibUInt64Array; AOff, ALen, AWords, AM: Int32; const AKs: TCryptoLibInt32Array); static;
- class procedure FlipVector(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, AYLen, ABits: Int32); static;
- public
- class function AreAliased(const A, B: TLongArray): Boolean; static;
- constructor Create(AIntLen: Int32); overload;
- constructor Create(const AData: TCryptoLibUInt64Array); overload;
- constructor Create(const AData: TCryptoLibUInt64Array; AOff, ALen: Int32); overload;
- constructor Create(const ABigInt: TBigInteger); overload;
-
- procedure CopyTo(const AZ: TCryptoLibUInt64Array; AZOff: Int32);
- function IsOne(): Boolean;
- function IsZero(): Boolean;
- function GetUsedLength(): Int32;
- function GetUsedLengthFrom(AFrom: Int32): Int32;
- function Degree(): Int32;
- function BitLength(): Int32; overload; inline;
- function ToBigInteger(): TBigInteger;
- function AddOne(): TLongArray;
- procedure AddShiftedByWords(const AOther: TLongArray; AWords: Int32);
- function TestBitZero(): Boolean;
- function ModMultiplyLD(const AOther: TLongArray; AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
- function ModMultiply(const AOther: TLongArray; AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
- function Multiply(const AOther: TLongArray): TLongArray; overload;
- function Multiply(const AOther: TLongArray; AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray; overload;
- procedure Reduce(AM: Int32; const AKs: TCryptoLibInt32Array);
- function ModSquare(AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
- function ModSquareN(AN, AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
- function Square(AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
- function ModInverse(AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
- function Copy(): TLongArray;
- function Equals(const AOther: TLongArray): Boolean;
- function GetHashCode(): Int32;
- function ToString(): String;
- end;
-
-implementation
-
-{ TLongArray }
-
-class function TLongArray.AreAliased(const A, B: TLongArray): Boolean;
-begin
- Result := A.FData = B.FData;
-end;
-
-constructor TLongArray.Create(AIntLen: Int32);
-begin
- System.SetLength(Self.FData, AIntLen);
-end;
-
-constructor TLongArray.Create(const AData: TCryptoLibUInt64Array);
-begin
- Self.FData := AData;
-end;
-
-constructor TLongArray.Create(const AData: TCryptoLibUInt64Array; AOff, ALen: Int32);
-var
- LData: TCryptoLibUInt64Array;
-begin
- if (AOff = 0) and (ALen = System.Length(AData)) then
- Self.FData := AData
- else
- begin
- LData := System.Copy(AData, AOff, ALen);
- Self.FData := LData;
- end;
-end;
-
-constructor TLongArray.Create(const ABigInt: TBigInteger);
-var
- LBarr: TCryptoLibByteArray;
- LBarrLen, LBarrStart, LIntLen, LIarrJ, LRem, LBarrI, LI: Int32;
- LTemp: UInt64;
-begin
- if (not ABigInt.IsInitialized) or (ABigInt.SignValue < 0) then
- raise EArgumentCryptoLibException.CreateRes(@SInvalidF2mFieldValue);
-
- if ABigInt.SignValue = 0 then
- begin
- System.SetLength(Self.FData, 1);
- Self.FData[0] := 0;
- Exit;
- end;
-
- LBarr := ABigInt.ToByteArray();
- LBarrLen := System.Length(LBarr);
- LBarrStart := 0;
- if LBarr[0] = 0 then
- begin
- System.Dec(LBarrLen);
- LBarrStart := 1;
- end;
- LIntLen := (LBarrLen + 7) div 8;
- System.SetLength(Self.FData, LIntLen);
-
- LIarrJ := LIntLen - 1;
- LRem := (LBarrLen mod 8) + LBarrStart;
- LTemp := 0;
- LBarrI := LBarrStart;
- if LBarrStart < LRem then
- begin
- while LBarrI < LRem do
- begin
- LTemp := (LTemp shl 8) or UInt64(LBarr[LBarrI]);
- System.Inc(LBarrI);
- end;
- Self.FData[LIarrJ] := LTemp;
- System.Dec(LIarrJ);
- end;
-
- while LIarrJ >= 0 do
- begin
- LTemp := 0;
- for LI := 0 to 7 do
- begin
- LTemp := (LTemp shl 8) or UInt64(LBarr[LBarrI]);
- System.Inc(LBarrI);
- end;
- Self.FData[LIarrJ] := LTemp;
- System.Dec(LIarrJ);
- end;
-end;
-
-procedure TLongArray.CopyTo(const AZ: TCryptoLibUInt64Array; AZOff: Int32);
-var
- LLen: Int32;
-begin
- LLen := System.Length(FData);
- if LLen > 0 then
- System.Move(FData[0], AZ[AZOff], LLen * SizeOf(UInt64));
-end;
-
-function TLongArray.IsOne(): Boolean;
-var
- LLen: Int32;
-begin
- LLen := System.Length(FData);
- Result := (LLen > 0) and (TNat.EqualToOne64(LLen, FData) <> 0);
-end;
-
-function TLongArray.IsZero(): Boolean;
-begin
- Result := TNat.EqualToZero64(System.Length(FData), FData) <> 0;
-end;
-
-function TLongArray.GetUsedLength(): Int32;
-begin
- Result := GetUsedLengthFrom(System.Length(FData));
-end;
-
-function TLongArray.GetUsedLengthFrom(AFrom: Int32): Int32;
-var
- LA: TCryptoLibUInt64Array;
-begin
- LA := FData;
- AFrom := Min(AFrom, System.Length(LA));
- if AFrom < 1 then
- Exit(0);
-
- if LA[0] <> 0 then
- begin
- repeat
- System.Dec(AFrom);
- if LA[AFrom] <> 0 then
- Break;
- until False;
- Exit(AFrom + 1);
- end;
-
- repeat
- System.Dec(AFrom);
- if LA[AFrom] <> 0 then
- Exit(AFrom + 1);
- until AFrom <= 0;
- Result := 0;
-end;
-
-class function TLongArray.BitLength(AW: UInt64): Int32;
-begin
- Result := TInt64Utilities.BitLength(AW);
-end;
-
-function TLongArray.Degree(): Int32;
-var
- LI: Int32;
- LW: UInt64;
-begin
- LI := System.Length(FData);
- repeat
- if LI = 0 then
- Exit(0);
- System.Dec(LI);
- LW := FData[LI];
- until LW <> 0;
- Result := (LI shl 6) + BitLength(LW);
-end;
-
-function TLongArray.DegreeFrom(ALimit: Int32): Int32;
-var
- LI: Int32;
- LW: UInt64;
-begin
- LI := Int32((UInt32(ALimit) + 62) shr 6);
- repeat
- if LI = 0 then
- Exit(0);
- System.Dec(LI);
- LW := FData[LI];
- until LW <> 0;
- Result := (LI shl 6) + BitLength(LW);
-end;
-
-function TLongArray.ResizedData(ANewLen: Int32): TCryptoLibUInt64Array;
-var
- LCount: Int32;
-begin
- System.SetLength(Result, ANewLen);
- LCount := Min(System.Length(FData), ANewLen);
- if LCount > 0 then
- System.Move(FData[0], Result[0], LCount * SizeOf(UInt64));
-end;
-
-function TLongArray.ToBigInteger(): TBigInteger;
-var
- LUsedLen, LBarrI, LBarrLen, LJ, LIarrJ: Int32;
- LHighestInt: UInt64;
- LTemp: TCryptoLibByteArray;
- LTrailingZeroBytesDone: Boolean;
- LThisByte: Byte;
- LBarr: TCryptoLibByteArray;
- LMI: UInt64;
-begin
- LUsedLen := GetUsedLength();
- if LUsedLen = 0 then
- Exit(TBigIntegerUtilities.Zero);
-
- LHighestInt := FData[LUsedLen - 1];
- System.SetLength(LTemp, 8);
- LBarrI := 0;
- LTrailingZeroBytesDone := False;
- for LJ := 7 downto 0 do
- begin
- LThisByte := Byte(LHighestInt shr (8 * LJ));
- if LTrailingZeroBytesDone or (LThisByte <> 0) then
- begin
- LTrailingZeroBytesDone := True;
- LTemp[LBarrI] := LThisByte;
- System.Inc(LBarrI);
- end;
- end;
-
- LBarrLen := 8 * (LUsedLen - 1) + LBarrI;
- System.SetLength(LBarr, LBarrLen);
- for LJ := 0 to LBarrI - 1 do
- LBarr[LJ] := LTemp[LJ];
-
- for LIarrJ := LUsedLen - 2 downto 0 do
- begin
- LMI := FData[LIarrJ];
- for LJ := 7 downto 0 do
- begin
- LBarr[LBarrI] := Byte(LMI shr (8 * LJ));
- System.Inc(LBarrI);
- end;
- end;
- Result := TBigInteger.Create(1, LBarr);
-end;
-
-class function TLongArray.ShiftUp(const AX: TCryptoLibUInt64Array; AXOff, ACount, AShift: Int32): UInt64;
-var
- LShiftInv: Int32;
- LPrev: UInt64;
- LI: Int32;
- LNext: UInt64;
-begin
- LShiftInv := 64 - AShift;
- LPrev := 0;
- for LI := 0 to ACount - 1 do
- begin
- LNext := AX[AXOff + LI];
- AX[AXOff + LI] := (LNext shl AShift) or LPrev;
- LPrev := LNext shr LShiftInv;
- end;
- Result := LPrev;
-end;
-
-class function TLongArray.ShiftUp(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff, ACount, AShift: Int32): UInt64;
-var
- LShiftInv: Int32;
- LPrev: UInt64;
- LI: Int32;
- LNext: UInt64;
-begin
- LShiftInv := 64 - AShift;
- LPrev := 0;
- for LI := 0 to ACount - 1 do
- begin
- LNext := AX[AXOff + LI];
- AZ[AZOff + LI] := (LNext shl AShift) or LPrev;
- LPrev := LNext shr LShiftInv;
- end;
- Result := LPrev;
-end;
-
-class function TLongArray.AddShiftedUp(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, ACount, AShift: Int32): UInt64;
-var
- LShiftInv: Int32;
- LPrev: UInt64;
- LI: Int32;
- LNext: UInt64;
-begin
- LShiftInv := 64 - AShift;
- LPrev := 0;
- for LI := 0 to ACount - 1 do
- begin
- LNext := AY[AYOff + LI];
- AX[AXOff + LI] := AX[AXOff + LI] xor ((LNext shl AShift) or LPrev);
- LPrev := LNext shr LShiftInv;
- end;
- Result := LPrev;
-end;
-
-class function TLongArray.AddShiftedDown(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, ACount, AShift: Int32): UInt64;
-var
- LShiftInv: Int32;
- LPrev: UInt64;
- LI: Int32;
- LNext: UInt64;
-begin
- LShiftInv := 64 - AShift;
- LPrev := 0;
- LI := ACount;
- while True do
- begin
- System.Dec(LI);
- if LI < 0 then
- Break;
- LNext := AY[AYOff + LI];
- AX[AXOff + LI] := AX[AXOff + LI] xor ((LNext shr AShift) or LPrev);
- LPrev := LNext shl LShiftInv;
- end;
- Result := LPrev;
-end;
-
-class procedure TLongArray.Add(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, ACount: Int32);
-begin
- TNat.XorTo64(ACount, AY, AYOff, AX, AXOff);
-end;
-
-class procedure TLongArray.Add(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff: Int32; const AZ: TCryptoLibUInt64Array; AZOff, ACount: Int32);
-begin
- TNat.Xor64(ACount, AX, AXOff, AY, AYOff, AZ, AZOff);
-end;
-
-class procedure TLongArray.AddBoth(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY1: TCryptoLibUInt64Array; AY1Off: Int32; const AY2: TCryptoLibUInt64Array; AY2Off, ACount: Int32);
-var
- LI: Int32;
-begin
- for LI := 0 to ACount - 1 do
- AX[AXOff + LI] := AX[AXOff + LI] xor (AY1[AY1Off + LI] xor AY2[AY2Off + LI]);
-end;
-
-procedure TLongArray.AddShiftedByBitsSafe(const AOther: TLongArray; AOtherDegree, ABits: Int32);
-var
- LOtherLen, LWords, LShift: Int32;
- LCarry: UInt64;
-begin
- LOtherLen := Int32((UInt32(AOtherDegree + 63) shr 6));
- LWords := Int32(UInt32(ABits) shr 6);
- LShift := ABits and $3F;
- if LShift = 0 then
- Add(FData, LWords, AOther.FData, 0, LOtherLen)
- else
- begin
- LCarry := AddShiftedUp(FData, LWords, AOther.FData, 0, LOtherLen, LShift);
- if LCarry <> 0 then
- FData[LOtherLen + LWords] := FData[LOtherLen + LWords] xor LCarry;
- end;
-end;
-
-procedure TLongArray.AddShiftedByWords(const AOther: TLongArray; AWords: Int32);
-var
- LOtherUsedLen, LMinLen: Int32;
-begin
- LOtherUsedLen := AOther.GetUsedLength();
- if LOtherUsedLen = 0 then
- Exit;
- LMinLen := LOtherUsedLen + AWords;
- if LMinLen > System.Length(FData) then
- FData := ResizedData(LMinLen);
- Add(FData, AWords, AOther.FData, 0, LOtherUsedLen);
-end;
-
-class procedure TLongArray.FlipWord(ABuf: TCryptoLibUInt64Array; AOff, ABit: Int32; AWord: UInt64);
-var
- LN: Int32;
- LShift: Int32;
-begin
- LN := AOff + Int32(UInt32(ABit) shr 6);
- LShift := ABit and $3F;
- if LShift = 0 then
- ABuf[LN] := ABuf[LN] xor AWord
- else
- begin
- ABuf[LN] := ABuf[LN] xor (AWord shl LShift);
- AWord := AWord shr (64 - LShift);
- if AWord <> 0 then
- begin
- System.Inc(LN);
- ABuf[LN] := ABuf[LN] xor AWord;
- end;
- end;
-end;
-
-function TLongArray.TestBitZero(): Boolean;
-begin
- Result := (System.Length(FData) > 0) and ((FData[0] and 1) <> 0);
-end;
-
-class function TLongArray.TestBit(const ABuf: TCryptoLibUInt64Array; AOff, AN: Int32): Boolean;
-var
- LTheInt: Int32;
- LTheBit: Int32;
- LTester: UInt64;
-begin
- LTheInt := Int32(UInt32(AN) shr 6);
- LTheBit := AN and $3F;
- LTester := UInt64(1) shl LTheBit;
- Result := (ABuf[AOff + LTheInt] and LTester) <> 0;
-end;
-
-class procedure TLongArray.FlipBit(ABuf: TCryptoLibUInt64Array; AOff, AN: Int32);
-var
- LTheInt: Int32;
- LTheBit: Int32;
- LFlipper: UInt64;
-begin
- LTheInt := Int32(UInt32(AN) shr 6);
- LTheBit := AN and $3F;
- LFlipper := UInt64(1) shl LTheBit;
- ABuf[AOff + LTheInt] := ABuf[AOff + LTheInt] xor LFlipper;
-end;
-
-class procedure TLongArray.MultiplyWord(AA: UInt64; const AB: TCryptoLibUInt64Array; ABLen: Int32; AC: TCryptoLibUInt64Array; ACOff: Int32);
-var
- LK: Int32;
- LCarry: UInt64;
-begin
- if (AA and 1) <> 0 then
- Add(AC, ACOff, AB, 0, ABLen);
- LK := 1;
- AA := AA shr 1;
- while AA <> 0 do
- begin
- if (AA and 1) <> 0 then
- begin
- LCarry := AddShiftedUp(AC, ACOff, AB, 0, ABLen, LK);
- if LCarry <> 0 then
- AC[ACOff + ABLen] := AC[ACOff + ABLen] xor LCarry;
- end;
- System.Inc(LK);
- AA := AA shr 1;
- end;
-end;
-
-class procedure TLongArray.ReduceBit(ABuf: TCryptoLibUInt64Array; AOff, ABit, AM: Int32; const AKs: TCryptoLibInt32Array);
-var
- LN: Int32;
- LJ: Int32;
-begin
- FlipBit(ABuf, AOff, ABit);
- LN := ABit - AM;
- LJ := System.Length(AKs);
- while True do
- begin
- System.Dec(LJ);
- if LJ < 0 then
- Break;
- FlipBit(ABuf, AOff, AKs[LJ] + LN);
- end;
- FlipBit(ABuf, AOff, LN);
-end;
-
-class procedure TLongArray.ReduceBitWise(ABuf: TCryptoLibUInt64Array; AOff, ABitLength, AM: Int32; const AKs: TCryptoLibInt32Array);
-begin
- while True do
- begin
- System.Dec(ABitLength);
- if ABitLength < AM then
- Break;
- if TestBit(ABuf, AOff, ABitLength) then
- ReduceBit(ABuf, AOff, ABitLength, AM, AKs);
- end;
-end;
-
-class procedure TLongArray.ReduceWord(ABuf: TCryptoLibUInt64Array; AOff, ABit: Int32; AWord: UInt64; AM: Int32; const AKs: TCryptoLibInt32Array);
-var
- LOffset: Int32;
- LJ: Int32;
-begin
- LOffset := ABit - AM;
- LJ := System.Length(AKs);
- while True do
- begin
- System.Dec(LJ);
- if LJ < 0 then
- Break;
- FlipWord(ABuf, AOff, LOffset + AKs[LJ], AWord);
- end;
- FlipWord(ABuf, AOff, LOffset, AWord);
-end;
-
-class procedure TLongArray.ReduceWordWise(ABuf: TCryptoLibUInt64Array; AOff, ALen, AToBit, AM: Int32; const AKs: TCryptoLibInt32Array);
-var
- LToPos: Int32;
- LPartial: Int32;
- LWord: UInt64;
-begin
- LToPos := Int32(UInt32(AToBit) shr 6);
- while True do
- begin
- System.Dec(ALen);
- if ALen <= LToPos then
- Break;
- LWord := ABuf[AOff + ALen];
- if LWord <> 0 then
- begin
- ABuf[AOff + ALen] := 0;
- ReduceWord(ABuf, AOff, ALen shl 6, LWord, AM, AKs);
- end;
- end;
- LPartial := AToBit and $3F;
- LWord := ABuf[AOff + LToPos] shr LPartial;
- if LWord <> 0 then
- begin
- ABuf[AOff + LToPos] := ABuf[AOff + LToPos] xor (LWord shl LPartial);
- ReduceWord(ABuf, AOff, AToBit, LWord, AM, AKs);
- end;
-end;
-
-class procedure TLongArray.FlipVector(const AX: TCryptoLibUInt64Array; AXOff: Int32; const AY: TCryptoLibUInt64Array; AYOff, AYLen, ABits: Int32);
-var
- LCarry: UInt64;
-begin
- AXOff := AXOff + Int32(UInt32(ABits) shr 6);
- ABits := ABits and $3F;
- if ABits = 0 then
- Add(AX, AXOff, AY, AYOff, AYLen)
- else
- begin
- LCarry := AddShiftedDown(AX, AXOff + 1, AY, AYOff, AYLen, 64 - ABits);
- AX[AXOff] := AX[AXOff] xor LCarry;
- end;
-end;
-
-class procedure TLongArray.ReduceVectorWise(ABuf: TCryptoLibUInt64Array; AOff, ALen, AWords, AM: Int32; const AKs: TCryptoLibInt32Array);
-var
- LBaseBit: Int32;
- LJ: Int32;
-begin
- LBaseBit := (AWords shl 6) - AM;
- LJ := System.Length(AKs);
- while True do
- begin
- System.Dec(LJ);
- if LJ < 0 then
- Break;
- FlipVector(ABuf, AOff, ABuf, AOff + AWords, ALen - AWords, LBaseBit + AKs[LJ]);
- end;
- FlipVector(ABuf, AOff, ABuf, AOff + AWords, ALen - AWords, LBaseBit);
-end;
-
-class function TLongArray.ReduceInPlace(ABuf: TCryptoLibUInt64Array; AOff, ALen, AM: Int32; const AKs: TCryptoLibInt32Array): Int32;
-var
- LMLen: Int32;
- LNumBits: Int32;
- LExcessBits: Int32;
- LKLen, LKMax, LKNext: Int32;
- LWordWiseLimit: Int32;
- LVectorableWords: Int32;
- LVectorWiseWords: Int32;
-begin
- LMLen := TBitOperations.Asr32(AM + 63, 6);
- if ALen < LMLen then
- Exit(ALen);
-
- LNumBits := Min(ALen shl 6, (AM shl 1) - 1);
- LExcessBits := (ALen shl 6) - LNumBits;
- while LExcessBits >= 64 do
- begin
- System.Dec(ALen);
- LExcessBits := LExcessBits - 64;
- end;
-
- LKLen := System.Length(AKs);
- LKMax := AKs[LKLen - 1];
- if LKLen > 1 then
- LKNext := AKs[LKLen - 2]
- else
- LKNext := 0;
- LWordWiseLimit := Max(AM, LKMax + 64);
- LVectorableWords := TBitOperations.Asr32(LExcessBits + Min(LNumBits - LWordWiseLimit, AM - LKNext), 6);
- if LVectorableWords > 1 then
- begin
- LVectorWiseWords := ALen - LVectorableWords;
- ReduceVectorWise(ABuf, AOff, ALen, LVectorWiseWords, AM, AKs);
- while ALen > LVectorWiseWords do
- begin
- System.Dec(ALen);
- ABuf[AOff + ALen] := 0;
- end;
- LNumBits := LVectorWiseWords shl 6;
- end;
-
- if LNumBits > LWordWiseLimit then
- begin
- ReduceWordWise(ABuf, AOff, ALen, LWordWiseLimit, AM, AKs);
- LNumBits := LWordWiseLimit;
- end;
-
- if LNumBits > AM then
- ReduceBitWise(ABuf, AOff, LNumBits, AM, AKs);
-
- Result := LMLen;
-end;
-
-class function TLongArray.ReduceResult(const ABuf: TCryptoLibUInt64Array; AOff, ALen, AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- RLen: Int32;
-begin
- RLen := ReduceInPlace(ABuf, AOff, ALen, AM, AKs);
- Result := TLongArray.Create(ABuf, AOff, RLen);
-end;
-
-function TLongArray.AddOne(): TLongArray;
-var
- LResultLen: Int32;
- LData: TCryptoLibUInt64Array;
-begin
- if System.Length(FData) = 0 then
- Exit(TLongArray.Create(TCryptoLibUInt64Array.Create(1)));
- LResultLen := Max(1, GetUsedLength());
- LData := ResizedData(LResultLen);
- LData[0] := LData[0] xor 1;
- Result := TLongArray.Create(LData);
-end;
-
-function TLongArray.ModMultiplyLD(const AOther: TLongArray; AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- LADeg, LBDeg, LALen, LBLen, LCLen: Int32;
- LA, LB: TLongArray;
- LA0: UInt64;
- LC0: TCryptoLibUInt64Array;
- LBMax, LTOff, LI: Int32;
- LTi: TCryptoLibInt32Array;
- LT0, LT1: TCryptoLibUInt64Array;
- LAArr: TCryptoLibUInt64Array;
- LC: TCryptoLibUInt64Array;
- LMask: UInt32;
- LK, LJ: Int32;
- LAVal: UInt32;
- LU, LV: UInt32;
-begin
- LADeg := Degree();
- if LADeg = 0 then
- Exit(Self);
- LBDeg := AOther.Degree();
- if LBDeg = 0 then
- Exit(AOther);
-
- LA := Self;
- LB := AOther;
- if LADeg > LBDeg then
- begin
- LA := AOther;
- LB := Self;
- LADeg := LBDeg;
- LBDeg := Degree();
- end;
-
- LALen := Int32((UInt32(LADeg + 63) shr 6));
- LBLen := Int32((UInt32(LBDeg + 63) shr 6));
- LCLen := Int32((UInt32(LADeg + LBDeg + 62) shr 6));
-
- if LALen = 1 then
- begin
- LA0 := LA.FData[0];
- if LA0 = 1 then
- Exit(LB);
- System.SetLength(LC0, LCLen);
- MultiplyWord(LA0, LB.FData, LBLen, LC0, 0);
- Result := ReduceResult(LC0, 0, LCLen, AM, AKs);
- Exit;
- end;
-
- LBMax := Int32((UInt32(LBDeg + 7 + 63) shr 6));
- System.SetLength(LTi, 16);
- System.SetLength(LT0, LBMax shl 4);
- LTOff := LBMax;
- LTi[1] := LTOff;
- for LI := 0 to LBLen - 1 do
- LT0[LTOff + LI] := LB.FData[LI];
- for LI := 2 to 15 do
- begin
- LTOff := LTOff + LBMax;
- LTi[LI] := LTOff;
- if (LI and 1) = 0 then
- ShiftUp(LT0, Int32(UInt32(LTOff) shr 1), LT0, LTOff, LBMax, 1)
- else
- Add(LT0, LBMax, LT0, LTOff - LBMax, LT0, LTOff, LBMax);
- end;
-
- System.SetLength(LT1, System.Length(LT0));
- ShiftUp(LT0, 0, LT1, 0, System.Length(LT0), 4);
-
- LAArr := LA.FData;
- System.SetLength(LC, LCLen);
- LMask := $F;
-
- LK := 56;
- while LK >= 0 do
- begin
- LJ := 1;
- while LJ < LALen do
- begin
- LAVal := UInt32(LAArr[LJ] shr LK);
- LU := LAVal and LMask;
- LV := (LAVal shr 4) and LMask;
- AddBoth(LC, LJ - 1, LT0, LTi[LU], LT1, LTi[LV], LBMax);
- LJ := LJ + 2;
- end;
- ShiftUp(LC, 0, LCLen, 8);
- LK := LK - 8;
- end;
-
- LK := 56;
- while LK >= 0 do
- begin
- LJ := 0;
- while LJ < LALen do
- begin
- LAVal := UInt32(LAArr[LJ] shr LK);
- LU := LAVal and LMask;
- LV := (LAVal shr 4) and LMask;
- AddBoth(LC, LJ, LT0, LTi[LU], LT1, LTi[LV], LBMax);
- LJ := LJ + 2;
- end;
- if LK > 0 then
- ShiftUp(LC, 0, LCLen, 8);
- LK := LK - 8;
- end;
-
- Result := ReduceResult(LC, 0, LCLen, AM, AKs);
-end;
-
-function TLongArray.ModMultiply(const AOther: TLongArray; AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- LADeg, LBDeg, LALen, LBLen, LCLen: Int32;
- LA, LB: TLongArray;
- LA0: UInt64;
- LC0: TCryptoLibUInt64Array;
- LBMax, LTOff, LI: Int32;
- LTi: TCryptoLibInt32Array;
- LT0, LT1: TCryptoLibUInt64Array;
- LAArr: TCryptoLibUInt64Array;
- LC: TCryptoLibUInt64Array;
- LMask: UInt32;
- LAPos: Int32;
- LAVal: UInt64;
- LCOff: Int32;
- LU, LV: UInt32;
- LCOff2: Int32;
-begin
- LADeg := Degree();
- if LADeg = 0 then
- Exit(Self);
- LBDeg := AOther.Degree();
- if LBDeg = 0 then
- Exit(AOther);
-
- LA := Self;
- LB := AOther;
- if LADeg > LBDeg then
- begin
- LA := AOther;
- LB := Self;
- LADeg := LBDeg;
- LBDeg := Degree();
- end;
-
- LALen := Int32((UInt32(LADeg + 63) shr 6));
- LBLen := Int32((UInt32(LBDeg + 63) shr 6));
- LCLen := Int32((UInt32(LADeg + LBDeg + 62) shr 6));
-
- if LALen = 1 then
- begin
- LA0 := LA.FData[0];
- if LA0 = 1 then
- Exit(LB);
- System.SetLength(LC0, LCLen);
- MultiplyWord(LA0, LB.FData, LBLen, LC0, 0);
- Exit(ReduceResult(LC0, 0, LCLen, AM, AKs));
- end;
-
- LBMax := Int32((UInt32(LBDeg + 7 + 63) shr 6));
- System.SetLength(LTi, 16);
- System.SetLength(LT0, LBMax shl 4);
- LTOff := LBMax;
- LTi[1] := LTOff;
- for LI := 0 to LBLen - 1 do
- LT0[LTOff + LI] := LB.FData[LI];
- for LI := 2 to 15 do
- begin
- LTOff := LTOff + LBMax;
- LTi[LI] := LTOff;
- if (LI and 1) = 0 then
- ShiftUp(LT0, Int32(UInt32(LTOff) shr 1), LT0, LTOff, LBMax, 1)
- else
- Add(LT0, LBMax, LT0, LTOff - LBMax, LT0, LTOff, LBMax);
- end;
-
- System.SetLength(LT1, System.Length(LT0));
- ShiftUp(LT0, 0, LT1, 0, System.Length(LT0), 4);
-
- LAArr := LA.FData;
- System.SetLength(LC, LCLen shl 3);
- LMask := $F;
-
- for LAPos := 0 to LALen - 1 do
- begin
- LAVal := LAArr[LAPos];
- LCOff := LAPos;
- while True do
- begin
- LU := UInt32(LAVal) and LMask;
- LAVal := LAVal shr 4;
- LV := UInt32(LAVal) and LMask;
- LAVal := LAVal shr 4;
- AddBoth(LC, LCOff, LT0, LTi[LU], LT1, LTi[LV], LBMax);
- if LAVal = 0 then
- Break;
- LCOff := LCOff + LCLen;
- end;
- end;
-
- LCOff2 := System.Length(LC);
- while True do
- begin
- LCOff2 := LCOff2 - LCLen;
- if LCOff2 <= 0 then
- Break;
- AddShiftedUp(LC, LCOff2 - LCLen, LC, LCOff2, LCLen, 8);
- end;
-
- Result := ReduceResult(LC, 0, LCLen, AM, AKs);
-end;
-
-function TLongArray.Multiply(const AOther: TLongArray): TLongArray;
-begin
- Result := Multiply(AOther, 0, nil);
-end;
-
-function TLongArray.Multiply(const AOther: TLongArray; AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- LADeg, LBDeg, LALen, LBLen, LCLen: Int32;
- LA, LB: TLongArray;
- LA0: UInt64;
- LC0: TCryptoLibUInt64Array;
- LBMax, LTOff, LI: Int32;
- LTi: TCryptoLibInt32Array;
- LT0, LT1: TCryptoLibUInt64Array;
- LAArr: TCryptoLibUInt64Array;
- LC: TCryptoLibUInt64Array;
- LMask: UInt32;
- LAPos: Int32;
- LAVal: UInt64;
- LCOff: Int32;
- LU, LV: UInt32;
- LCOff2: Int32;
-begin
- LADeg := Degree();
- if LADeg = 0 then
- Exit(Self);
- LBDeg := AOther.Degree();
- if LBDeg = 0 then
- Exit(AOther);
-
- LA := Self;
- LB := AOther;
- if LADeg > LBDeg then
- begin
- LA := AOther;
- LB := Self;
- LADeg := LBDeg;
- LBDeg := Degree();
- end;
-
- LALen := Int32((UInt32(LADeg + 63) shr 6));
- LBLen := Int32((UInt32(LBDeg + 63) shr 6));
- LCLen := Int32((UInt32(LADeg + LBDeg + 62) shr 6));
-
- if LALen = 1 then
- begin
- LA0 := LA.FData[0];
- if LA0 = 1 then
- Exit(LB);
- System.SetLength(LC0, LCLen);
- MultiplyWord(LA0, LB.FData, LBLen, LC0, 0);
- Exit(TLongArray.Create(LC0, 0, LCLen));
- end;
-
- LBMax := Int32((UInt32(LBDeg + 7 + 63) shr 6));
- System.SetLength(LTi, 16);
- System.SetLength(LT0, LBMax shl 4);
- LTOff := LBMax;
- LTi[1] := LTOff;
- for LI := 0 to LBLen - 1 do
- LT0[LTOff + LI] := LB.FData[LI];
- for LI := 2 to 15 do
- begin
- LTOff := LTOff + LBMax;
- LTi[LI] := LTOff;
- if (LI and 1) = 0 then
- ShiftUp(LT0, Int32(UInt32(LTOff) shr 1), LT0, LTOff, LBMax, 1)
- else
- Add(LT0, LBMax, LT0, LTOff - LBMax, LT0, LTOff, LBMax);
- end;
-
- System.SetLength(LT1, System.Length(LT0));
- ShiftUp(LT0, 0, LT1, 0, System.Length(LT0), 4);
-
- LAArr := LA.FData;
- System.SetLength(LC, LCLen shl 3);
- LMask := $F;
-
- for LAPos := 0 to LALen - 1 do
- begin
- LAVal := LAArr[LAPos];
- LCOff := LAPos;
- while True do
- begin
- LU := UInt32(LAVal) and LMask;
- LAVal := LAVal shr 4;
- LV := UInt32(LAVal) and LMask;
- LAVal := LAVal shr 4;
- AddBoth(LC, LCOff, LT0, LTi[LU], LT1, LTi[LV], LBMax);
- if LAVal = 0 then
- Break;
- LCOff := LCOff + LCLen;
- end;
- end;
-
- LCOff2 := System.Length(LC);
- while True do
- begin
- LCOff2 := LCOff2 - LCLen;
- if LCOff2 <= 0 then
- Break;
- AddShiftedUp(LC, LCOff2 - LCLen, LC, LCOff2, LCLen, 8);
- end;
-
- Result := TLongArray.Create(LC, 0, LCLen);
-end;
-
-procedure TLongArray.Reduce(AM: Int32; const AKs: TCryptoLibInt32Array);
-var
- LBuf: TCryptoLibUInt64Array;
- RLen: Int32;
- LNewData: TCryptoLibUInt64Array;
-begin
- LBuf := FData;
- RLen := ReduceInPlace(LBuf, 0, System.Length(LBuf), AM, AKs);
- if RLen < System.Length(LBuf) then
- begin
- System.SetLength(LNewData, RLen);
- if RLen > 0 then
- System.Move(LBuf[0], LNewData[0], RLen * SizeOf(UInt64));
- FData := LNewData;
- end;
-end;
-
-function TLongArray.ModSquare(AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- LLen: Int32;
- LR: TCryptoLibUInt64Array;
- RLen: Int32;
-begin
- LLen := GetUsedLength();
- if LLen = 0 then
- Exit(Self);
- System.SetLength(LR, LLen shl 1);
- TInterleave.Expand64To128(FData, 0, LLen, LR, 0);
- RLen := ReduceInPlace(LR, 0, System.Length(LR), AM, AKs);
- Result := TLongArray.Create(LR, 0, RLen);
-end;
-
-function TLongArray.ModSquareN(AN, AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- LLen: Int32;
- LMLen: Int32;
- LR: TCryptoLibUInt64Array;
- LI: Int32;
-begin
- LLen := GetUsedLength();
- if LLen = 0 then
- Exit(Self);
- LMLen := TBitOperations.Asr32(AM + 63, 6);
- System.SetLength(LR, LMLen shl 1);
- if LLen > 0 then
- System.Move(FData[0], LR[0], LLen * SizeOf(UInt64));
- for LI := AN - 1 downto 0 do
- begin
- TInterleave.Expand64To128(LR, 0, LLen, LR, 0);
- LLen := ReduceInPlace(LR, 0, System.Length(LR), AM, AKs);
- end;
- Result := TLongArray.Create(LR, 0, LLen);
-end;
-
-function TLongArray.Square(AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- LLen: Int32;
- LR: TCryptoLibUInt64Array;
-begin
- LLen := GetUsedLength();
- if LLen = 0 then
- Exit(Self);
- System.SetLength(LR, LLen shl 1);
- TInterleave.Expand64To128(FData, 0, LLen, LR, 0);
- Result := TLongArray.Create(LR, 0, System.Length(LR));
-end;
-
-function TLongArray.ModInverse(AM: Int32; const AKs: TCryptoLibInt32Array): TLongArray;
-var
- LUzDegree: Int32;
- LT: Int32;
- LUz: TLongArray;
- LVz: TLongArray;
- LG1z: TLongArray;
- LG2z: TLongArray;
- LUvDeg: TCryptoLibInt32Array;
- LUv: array [0 .. 1] of TLongArray;
- LGgDeg: TCryptoLibInt32Array;
- LGg: array [0 .. 1] of TLongArray;
- LB, LDuv1, LDgg1, LJ, LDuv2, LDgg2: Int32;
-begin
- LUzDegree := Degree();
- if LUzDegree = 0 then
- raise EArgumentCryptoLibException.Create('');
- if LUzDegree = 1 then
- Exit(Self);
-
- LUz := Copy();
- LT := TBitOperations.Asr32(AM + 63, 6);
-
- LVz := TLongArray.Create(LT);
- ReduceBit(LVz.FData, 0, AM, AM, AKs);
-
- LG1z := TLongArray.Create(LT);
- LG1z.FData[0] := 1;
- LG2z := TLongArray.Create(LT);
-
- LUvDeg := TCryptoLibInt32Array.Create(LUzDegree, AM + 1);
- LUv[0] := LUz;
- LUv[1] := LVz;
-
- LGgDeg := TCryptoLibInt32Array.Create(1, 0);
- LGg[0] := LG1z;
- LGg[1] := LG2z;
-
- LB := 1;
- LDuv1 := LUvDeg[LB];
- LDgg1 := LGgDeg[LB];
- LJ := LDuv1 - LUvDeg[1 - LB];
-
- while True do
- begin
- if LJ < 0 then
- begin
- LJ := -LJ;
- LUvDeg[LB] := LDuv1;
- LGgDeg[LB] := LDgg1;
- LB := 1 - LB;
- LDuv1 := LUvDeg[LB];
- LDgg1 := LGgDeg[LB];
- end;
-
- LUv[LB].AddShiftedByBitsSafe(LUv[1 - LB], LUvDeg[1 - LB], LJ);
-
- LDuv2 := LUv[LB].DegreeFrom(LDuv1);
- if LDuv2 = 0 then
- Exit(LGg[1 - LB]);
-
- LDgg2 := LGgDeg[1 - LB];
- LGg[LB].AddShiftedByBitsSafe(LGg[1 - LB], LDgg2, LJ);
- LDgg2 := LDgg2 + LJ;
-
- if LDgg2 > LDgg1 then
- LDgg1 := LDgg2
- else if LDgg2 = LDgg1 then
- LDgg1 := LGg[LB].DegreeFrom(LDgg1);
-
- LJ := LJ + (LDuv2 - LDuv1);
- LDuv1 := LDuv2;
- end;
-end;
-
-function TLongArray.Copy(): TLongArray;
-var
- LCloned: TCryptoLibUInt64Array;
-begin
- LCloned := System.Copy(FData, 0, System.Length(FData));
- Result := TLongArray.Create(LCloned);
-end;
-
-function TLongArray.Equals(const AOther: TLongArray): Boolean;
-var
- LUsedLen: Int32;
-begin
- if AreAliased(Self, AOther) then
- Exit(True);
- LUsedLen := GetUsedLength();
- Result := (AOther.GetUsedLength() = LUsedLen) and (TNat.EqualTo64(LUsedLen, FData, AOther.FData) <> 0);
-end;
-
-function TLongArray.GetHashCode(): Int32;
-begin
- Result := TArrayUtilities.GetArrayHashCode(FData, 0, GetUsedLength());
-end;
-
-function TLongArray.ToString(): String;
-var
- LI: Int32;
- LS: String;
- LW: UInt64;
- LB: Int32;
-begin
- LI := GetUsedLength();
- if LI = 0 then
- Exit('0');
- System.Dec(LI);
- LW := FData[LI];
- Result := '';
- for LB := 63 downto 0 do
- if (LW shr LB) and 1 <> 0 then
- Result := Result + '1'
- else if System.Length(Result) > 0 then
- Result := Result + '0';
- if Result = '' then
- Result := '0';
- while LI > 0 do
- begin
- System.Dec(LI);
- LW := FData[LI];
- LS := '';
- for LB := 63 downto 0 do
- if (LW shr LB) and 1 <> 0 then
- LS := LS + '1'
- else
- LS := LS + '0';
- Result := Result + LS;
- end;
-end;
-
-function TLongArray.BitLength(): Int32;
-var
- LI: Int32;
- LW: UInt64;
-begin
- LI := System.Length(FData);
- repeat
- if LI = 0 then
- Exit(0);
- System.Dec(LI);
- LW := FData[LI];
- until LW <> 0;
- Result := (LI shl 6) + BitLength(LW);
-end;
-
-end.
diff --git a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256K1Custom.pas b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256K1Custom.pas
index 324f49f5..688fb9e3 100644
--- a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256K1Custom.pas
+++ b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256K1Custom.pas
@@ -53,7 +53,6 @@ TSecP256K1Field = class sealed(TObject)
PInv33 = UInt32($3D1);
class var
FP, FPExt, FPExtInv: TCryptoLibUInt32Array;
- class procedure Boot; static;
class constructor Create;
public
class procedure Add(const AX, AY, AZ: TCryptoLibUInt32Array); static;
@@ -90,7 +89,6 @@ TSecP256K1FieldElement = class sealed(TAbstractFpFieldElement,
strict private
class var
FQ: TBigInteger;
- class procedure Boot; static;
class constructor Create;
strict protected
FX: TCryptoLibUInt32Array;
@@ -168,7 +166,6 @@ TSecP256K1LookupTable = class sealed(TAbstractECLookupTable, IECLookupTable,
class var
FQ: TBigInteger;
FSecP256K1AffineZs: TCryptoLibGenericArray;
- class procedure Boot; static;
class constructor Create;
var
FInfinity: ISecP256K1Point;
@@ -199,20 +196,15 @@ implementation
{ TSecP256K1Field }
-class procedure TSecP256K1Field.Boot;
+class constructor TSecP256K1Field.Create;
begin
FP := TCryptoLibUInt32Array.Create($FFFFFC2F, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
FPExt := TCryptoLibUInt32Array.Create($000E90A1, $000007A2, $00000001, $00000000,
- $00000000, $00000000, $00000000, $00000000, $FFFFF85E, $FFFFFFFD, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
+ $00000000, $00000000, $00000000, $00000000, $FFFFF85E, $FFFFFFFD, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
FPExtInv := TCryptoLibUInt32Array.Create($FFF16F5F, $FFFFF85D, $FFFFFFFE, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $000007A1, $00000002);
-end;
-
-class constructor TSecP256K1Field.Create;
-begin
- Boot;
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $000007A1, $00000002);
end;
class procedure TSecP256K1Field.Add(const AX, AY, AZ: TCryptoLibUInt32Array);
@@ -430,14 +422,9 @@ class procedure TSecP256K1Field.Twice(const AX, AZ: TCryptoLibUInt32Array);
{ TSecP256K1FieldElement }
-class procedure TSecP256K1FieldElement.Boot;
-begin
- FQ := TBigInteger.Create(1, THexEncoder.Decode('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'));
-end;
-
class constructor TSecP256K1FieldElement.Create;
begin
- Boot;
+ FQ := TBigInteger.Create(1, THexEncoder.Decode('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'));
end;
constructor TSecP256K1FieldElement.Create(const AX: TBigInteger);
@@ -932,16 +919,11 @@ function TSecP256K1Curve.TSecP256K1LookupTable.LookupVar(AIndex: Int32): IECPoin
{ TSecP256K1Curve }
-class procedure TSecP256K1Curve.Boot;
+class constructor TSecP256K1Curve.Create;
begin
FQ := TSecP256K1FieldElement.Q;
FSecP256K1AffineZs := TCryptoLibGenericArray.Create(
- TSecP256K1FieldElement.Create(TBigInteger.One) as IECFieldElement);
-end;
-
-class constructor TSecP256K1Curve.Create;
-begin
- Boot;
+ TSecP256K1FieldElement.Create(TBigInteger.One) as IECFieldElement);
end;
constructor TSecP256K1Curve.Create;
diff --git a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256R1Custom.pas b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256R1Custom.pas
index 34166609..69b16dd7 100644
--- a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256R1Custom.pas
+++ b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP256R1Custom.pas
@@ -52,7 +52,6 @@ TSecP256R1Field = class sealed(TObject)
PExt15 = UInt32($FFFFFFFE);
class var
FP, FPExt: TCryptoLibUInt32Array;
- class procedure Boot; static;
class procedure AddPInvTo(const AZ: TCryptoLibUInt32Array); static;
class procedure SubPInvFrom(const AZ: TCryptoLibUInt32Array); static;
class constructor Create;
@@ -91,7 +90,6 @@ TSecP256R1FieldElement = class sealed(TAbstractFpFieldElement,
strict private
class var
FQ: TBigInteger;
- class procedure Boot; static;
class constructor Create;
strict protected
FX: TCryptoLibUInt32Array;
@@ -169,7 +167,6 @@ TSecP256R1LookupTable = class sealed(TAbstractECLookupTable, IECLookupTable,
class var
FQ: TBigInteger;
FSecP256R1AffineZs: TCryptoLibGenericArray;
- class procedure Boot; static;
class constructor Create;
var
FInfinity: ISecP256R1Point;
@@ -200,18 +197,13 @@ implementation
{ TSecP256R1Field }
-class procedure TSecP256R1Field.Boot;
+class constructor TSecP256R1Field.Create;
begin
FP := TCryptoLibUInt32Array.Create($FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $00000000,
- $00000000, $00000000, $00000001, $FFFFFFFF);
+ $00000000, $00000000, $00000001, $FFFFFFFF);
FPExt := TCryptoLibUInt32Array.Create($00000001, $00000000, $00000000, $FFFFFFFE,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFE, $00000001, $FFFFFFFE, $00000001, $FFFFFFFE,
- $00000001, $00000001, $FFFFFFFE, $00000002, $FFFFFFFE);
-end;
-
-class constructor TSecP256R1Field.Create;
-begin
- Boot;
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFE, $00000001, $FFFFFFFE, $00000001, $FFFFFFFE,
+ $00000001, $00000001, $FFFFFFFE, $00000002, $FFFFFFFE);
end;
class procedure TSecP256R1Field.AddPInvTo(const AZ: TCryptoLibUInt32Array);
@@ -586,14 +578,9 @@ class procedure TSecP256R1Field.Twice(const AX, AZ: TCryptoLibUInt32Array);
{ TSecP256R1FieldElement }
-class procedure TSecP256R1FieldElement.Boot;
-begin
- FQ := TBigInteger.Create(1, THexEncoder.Decode('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF'));
-end;
-
class constructor TSecP256R1FieldElement.Create;
begin
- Boot;
+ FQ := TBigInteger.Create(1, THexEncoder.Decode('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF'));
end;
class function TSecP256R1FieldElement.GetQ: TBigInteger;
@@ -1088,16 +1075,11 @@ function TSecP256R1Curve.TSecP256R1LookupTable.LookupVar(AIndex: Int32): IECPoin
{ TSecP256R1Curve }
-class procedure TSecP256R1Curve.Boot;
+class constructor TSecP256R1Curve.Create;
begin
FQ := TSecP256R1FieldElement.Q;
FSecP256R1AffineZs := TCryptoLibGenericArray.Create(
- TSecP256R1FieldElement.Create(TBigInteger.One) as IECFieldElement);
-end;
-
-class constructor TSecP256R1Curve.Create;
-begin
- Boot;
+ TSecP256R1FieldElement.Create(TBigInteger.One) as IECFieldElement);
end;
constructor TSecP256R1Curve.Create;
diff --git a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP384R1Custom.pas b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP384R1Custom.pas
index 4ee7847a..4ea583de 100644
--- a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP384R1Custom.pas
+++ b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP384R1Custom.pas
@@ -52,7 +52,6 @@ TSecP384R1Field = class sealed(TObject)
PExt23 = UInt32($FFFFFFFF);
class var
FP, FPExt, FPExtInv: TCryptoLibUInt32Array;
- class procedure Boot; static;
class procedure AddPInvTo(const AZ: TCryptoLibUInt32Array); static;
class procedure SubPInvFrom(const AZ: TCryptoLibUInt32Array); static;
class constructor Create;
@@ -90,7 +89,6 @@ TSecP384R1FieldElement = class sealed(TAbstractFpFieldElement,
strict private
class var
FQ: TBigInteger;
- class procedure Boot; static;
class constructor Create;
strict protected
FX: TCryptoLibUInt32Array;
@@ -168,7 +166,6 @@ TSecP384R1LookupTable = class sealed(TAbstractECLookupTable, IECLookupTable,
class var
FQ: TBigInteger;
FSecP384R1AffineZs: TCryptoLibGenericArray;
- class procedure Boot; static;
class constructor Create;
var
FInfinity: ISecP384R1Point;
@@ -199,22 +196,17 @@ implementation
{ TSecP384R1Field }
-class procedure TSecP384R1Field.Boot;
+class constructor TSecP384R1Field.Create;
begin
FP := TCryptoLibUInt32Array.Create($FFFFFFFF, $00000000, $00000000, $FFFFFFFF,
- $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
+ $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
FPExt := TCryptoLibUInt32Array.Create($00000001, $FFFFFFFE, $00000000, $00000002,
- $00000000, $FFFFFFFE, $00000000, $00000002, $00000001, $00000000, $00000000, $00000000,
- $FFFFFFFE, $00000001, $00000000, $FFFFFFFE, $FFFFFFFD, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
+ $00000000, $FFFFFFFE, $00000000, $00000002, $00000001, $00000000, $00000000, $00000000,
+ $FFFFFFFE, $00000001, $00000000, $FFFFFFFE, $FFFFFFFD, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
FPExtInv := TCryptoLibUInt32Array.Create($FFFFFFFF, $00000001, $FFFFFFFF, $FFFFFFFD,
- $FFFFFFFF, $00000001, $FFFFFFFF, $FFFFFFFD, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $00000001, $FFFFFFFE, $FFFFFFFF, $00000001, $00000002);
-end;
-
-class constructor TSecP384R1Field.Create;
-begin
- Boot;
+ $FFFFFFFF, $00000001, $FFFFFFFF, $FFFFFFFD, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+ $00000001, $FFFFFFFE, $FFFFFFFF, $00000001, $00000002);
end;
class procedure TSecP384R1Field.AddPInvTo(const AZ: TCryptoLibUInt32Array);
@@ -565,14 +557,9 @@ class procedure TSecP384R1Field.Twice(const AX, AZ: TCryptoLibUInt32Array);
{ TSecP384R1FieldElement }
-class procedure TSecP384R1FieldElement.Boot;
-begin
- FQ := TBigInteger.Create(1, THexEncoder.Decode('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF'));
-end;
-
class constructor TSecP384R1FieldElement.Create;
begin
- Boot;
+ FQ := TBigInteger.Create(1, THexEncoder.Decode('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF'));
end;
class function TSecP384R1FieldElement.GetQ: TBigInteger;
@@ -1091,16 +1078,11 @@ function TSecP384R1Curve.TSecP384R1LookupTable.LookupVar(AIndex: Int32): IECPoin
{ TSecP384R1Curve }
-class procedure TSecP384R1Curve.Boot;
+class constructor TSecP384R1Curve.Create;
begin
FQ := TSecP384R1FieldElement.Q;
FSecP384R1AffineZs := TCryptoLibGenericArray.Create(
- TSecP384R1FieldElement.Create(TBigInteger.One) as IECFieldElement);
-end;
-
-class constructor TSecP384R1Curve.Create;
-begin
- Boot;
+ TSecP384R1FieldElement.Create(TBigInteger.One) as IECFieldElement);
end;
constructor TSecP384R1Curve.Create;
diff --git a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP521R1Custom.pas b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP521R1Custom.pas
index 7e1abfc0..2056867a 100644
--- a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP521R1Custom.pas
+++ b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecP521R1Custom.pas
@@ -51,7 +51,6 @@ TSecP521R1Field = class sealed(TObject)
P16 = UInt32($1FF);
class var
FP: TCryptoLibUInt32Array;
- class procedure Boot; static;
class procedure ImplMultiply(const AX, AY, AZZ: TCryptoLibUInt32Array); static;
class procedure ImplSquare(const AX, AZZ: TCryptoLibUInt32Array); static;
class constructor Create;
@@ -87,7 +86,6 @@ TSecP521R1FieldElement = class sealed(TAbstractFpFieldElement,
strict private
class var
FQ: TBigInteger;
- class procedure Boot; static;
class constructor Create;
strict protected
FX: TCryptoLibUInt32Array;
@@ -165,7 +163,6 @@ TSecP521R1LookupTable = class sealed(TAbstractECLookupTable, IECLookupTable,
class var
FQ: TBigInteger;
FSecP521R1AffineZs: TCryptoLibGenericArray;
- class procedure Boot; static;
class constructor Create;
var
FInfinity: ISecP521R1Point;
@@ -196,16 +193,11 @@ implementation
{ TSecP521R1Field }
-class procedure TSecP521R1Field.Boot;
-begin
- FP := TCryptoLibUInt32Array.Create($FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $1FF);
-end;
-
class constructor TSecP521R1Field.Create;
begin
- Boot;
+ FP := TCryptoLibUInt32Array.Create($FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $1FF);
end;
class procedure TSecP521R1Field.ImplMultiply(const AX, AY, AZZ: TCryptoLibUInt32Array);
@@ -446,14 +438,9 @@ class procedure TSecP521R1Field.Twice(const AX, AZ: TCryptoLibUInt32Array);
{ TSecP521R1FieldElement }
-class procedure TSecP521R1FieldElement.Boot;
-begin
- FQ := TBigInteger.Create(1, THexEncoder.Decode('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'));
-end;
-
class constructor TSecP521R1FieldElement.Create;
begin
- Boot;
+ FQ := TBigInteger.Create(1, THexEncoder.Decode('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'));
end;
class function TSecP521R1FieldElement.GetQ: TBigInteger;
@@ -923,16 +910,11 @@ function TSecP521R1Curve.TSecP521R1LookupTable.LookupVar(AIndex: Int32): IECPoin
{ TSecP521R1Curve }
-class procedure TSecP521R1Curve.Boot;
+class constructor TSecP521R1Curve.Create;
begin
FQ := TSecP521R1FieldElement.Q;
FSecP521R1AffineZs := TCryptoLibGenericArray.Create(
- TSecP521R1FieldElement.Create(TBigInteger.One) as IECFieldElement);
-end;
-
-class constructor TSecP521R1Curve.Create;
-begin
- Boot;
+ TSecP521R1FieldElement.Create(TBigInteger.One) as IECFieldElement);
end;
constructor TSecP521R1Curve.Create;
diff --git a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecT283K1Custom.pas b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecT283K1Custom.pas
index 8b010e86..a04a1173 100644
--- a/CryptoLib/src/Math/EC/Custom/Sec/ClpSecT283K1Custom.pas
+++ b/CryptoLib/src/Math/EC/Custom/Sec/ClpSecT283K1Custom.pas
@@ -51,7 +51,6 @@ TSecT283Field = class sealed(TObject)
M57: UInt64 = UInt64.MaxValue shr 7;
class var
FRootZ: TCryptoLibUInt64Array;
- class procedure Boot; static;
class procedure ImplCompactExt(const AZz: TCryptoLibUInt64Array); static;
class procedure ImplExpand(const AX: TCryptoLibUInt64Array;
const AZ: TCryptoLibUInt64Array); static;
@@ -175,7 +174,6 @@ TSecT283K1LookupTable = class sealed(TAbstractECLookupTable, IECLookupTable,
end;
class var
FSecT283K1AffineZs: TCryptoLibGenericArray;
- class procedure Boot; static;
class constructor Create;
var
FInfinity: ISecT283K1Point;
@@ -208,15 +206,10 @@ implementation
{ TSecT283Field }
-class procedure TSecT283Field.Boot;
-begin
- FRootZ := TCryptoLibUInt64Array.Create($0C30C30C30C30808, $30C30C30C30C30C3,
- UInt64($820820820820830C), $0820820820820820, $2082082);
-end;
-
class constructor TSecT283Field.Create;
begin
- Boot;
+ FRootZ := TCryptoLibUInt64Array.Create($0C30C30C30C30808, $30C30C30C30C30C3,
+ UInt64($820820820820830C), $0820820820820820, $2082082);
end;
class procedure TSecT283Field.ImplCompactExt(const AZz: TCryptoLibUInt64Array);
@@ -279,7 +272,7 @@ class procedure TSecT283Field.ImplMulw(const AU: TCryptoLibUInt64Array; AX, AY:
xor (AU[Int32(LJ shr 3) and 7] shl 3)
xor (AU[Int32(LJ shr 6) and 7] shl 6);
LL := LL xor (LG shl LK);
- LH := LH xor (UInt64(Int64(LG) shr (64 - LK)));
+ LH := LH xor TBitOperations.NegativeRightShift64(LG, -LK);
Dec(LK, 9);
until LK <= 0;
@@ -1208,15 +1201,10 @@ function TSecT283K1Curve.TSecT283K1LookupTable.LookupVar(AIndex: Int32): IECPoin
{ TSecT283K1Curve }
-class procedure TSecT283K1Curve.Boot;
-begin
- FSecT283K1AffineZs := TCryptoLibGenericArray.Create(
- TSecT283FieldElement.Create(TBigInteger.One) as IECFieldElement);
-end;
-
class constructor TSecT283K1Curve.Create;
begin
- Boot;
+ FSecT283K1AffineZs := TCryptoLibGenericArray.Create(
+ TSecT283FieldElement.Create(TBigInteger.One) as IECFieldElement);
end;
constructor TSecT283K1Curve.Create;
diff --git a/CryptoLib/src/Math/EC/Rfc7748/ClpX25519.pas b/CryptoLib/src/Math/EC/Rfc7748/ClpX25519.pas
index 0e69d42d..e82f7551 100644
--- a/CryptoLib/src/Math/EC/Rfc7748/ClpX25519.pas
+++ b/CryptoLib/src/Math/EC/Rfc7748/ClpX25519.pas
@@ -56,8 +56,6 @@ TX25519 = class sealed
class procedure GeneratePublicKey(const AK: TCryptoLibByteArray; AKOff: Int32;
AR: TCryptoLibByteArray; AROff: Int32); static;
- class procedure Precompute; static;
-
class procedure ScalarMult(const AK: TCryptoLibByteArray; AKOff: Int32;
const AU: TCryptoLibByteArray; AUOff: Int32; AR: TCryptoLibByteArray; AROff: Int32); static;
@@ -131,11 +129,6 @@ class procedure TX25519.PointDouble(AX, AZ: TCryptoLibInt32Array);
TX25519Field.Mul(AZ, LA, AZ);
end;
-class procedure TX25519.Precompute;
-begin
- TEd25519.Precompute();
-end;
-
class procedure TX25519.ScalarMult(const AK: TCryptoLibByteArray; AKOff: Int32;
const AU: TCryptoLibByteArray; AUOff: Int32; AR: TCryptoLibByteArray; AROff: Int32);
var
diff --git a/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas b/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas
index fe8efe9d..6d0313c1 100644
--- a/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas
+++ b/CryptoLib/src/Math/EC/Rfc7748/ClpX25519Field.pas
@@ -40,7 +40,6 @@ TX25519Field = class sealed
class var
FP32: TCryptoLibUInt32Array;
FRootNegOne: TCryptoLibInt32Array;
- class procedure Boot; static;
class constructor Create;
class procedure Decode128(const AX: TCryptoLibUInt32Array; AXOff: Int32;
const AZ: TCryptoLibInt32Array; AZOff: Int32); overload; static;
@@ -116,16 +115,11 @@ TX25519Field = class sealed
implementation
class constructor TX25519Field.Create;
-begin
- Boot;
-end;
-
-class procedure TX25519Field.Boot;
begin
FP32 := TCryptoLibUInt32Array.Create($FFFFFFED, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $7FFFFFFF);
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $7FFFFFFF);
FRootNegOne := TCryptoLibInt32Array.Create(-$01F15F50, -$0079362D, $00478C4F, $0035697F,
- $005E8630, $01FBD7A7, -$00BFD9B1, -$000F4D4B, $00027E0F, $00570649);
+ $005E8630, $01FBD7A7, -$00BFD9B1, -$000F4D4B, $00027E0F, $00570649);
end;
class procedure TX25519Field.Add(const AX, AY, AZ: TCryptoLibInt32Array);
diff --git a/CryptoLib/src/Math/EC/Rfc7748/ClpX448.pas b/CryptoLib/src/Math/EC/Rfc7748/ClpX448.pas
index f8df0683..aeb0ea17 100644
--- a/CryptoLib/src/Math/EC/Rfc7748/ClpX448.pas
+++ b/CryptoLib/src/Math/EC/Rfc7748/ClpX448.pas
@@ -57,8 +57,6 @@ TX448 = class sealed
class procedure GeneratePublicKey(const AK: TCryptoLibByteArray; AKOff: Int32;
AR: TCryptoLibByteArray; AROff: Int32); static;
- class procedure Precompute; static;
-
class procedure ScalarMult(const AK: TCryptoLibByteArray; AKOff: Int32;
const AU: TCryptoLibByteArray; AUOff: Int32; AR: TCryptoLibByteArray;
AROff: Int32); static;
@@ -133,11 +131,6 @@ class procedure TX448.PointDouble(AX, AZ: TCryptoLibUInt32Array);
TX448Field.Mul(AZ, LA, AZ);
end;
-class procedure TX448.Precompute;
-begin
- TEd448.Precompute;
-end;
-
class procedure TX448.ScalarMult(const AK: TCryptoLibByteArray; AKOff: Int32;
const AU: TCryptoLibByteArray; AUOff: Int32; AR: TCryptoLibByteArray;
AROff: Int32);
diff --git a/CryptoLib/src/Math/EC/Rfc7748/ClpX448Field.pas b/CryptoLib/src/Math/EC/Rfc7748/ClpX448Field.pas
index df37e7ea..e30c8a8b 100644
--- a/CryptoLib/src/Math/EC/Rfc7748/ClpX448Field.pas
+++ b/CryptoLib/src/Math/EC/Rfc7748/ClpX448Field.pas
@@ -37,7 +37,6 @@ TX448Field = class sealed
M28 = UInt32($0FFFFFFF);
class var
FP32: TCryptoLibUInt32Array;
- class procedure Boot; static;
class constructor Create;
class procedure Decode224(const AX: TCryptoLibUInt32Array; AXOff: Int32;
const AZ: TCryptoLibUInt32Array; AZOff: Int32); static;
@@ -118,15 +117,10 @@ TX448Field = class sealed
implementation
class constructor TX448Field.Create;
-begin
- Boot;
-end;
-
-class procedure TX448Field.Boot;
begin
FP32 := TCryptoLibUInt32Array.Create($FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
end;
class procedure TX448Field.Add(const AX, AY, AZ: TCryptoLibUInt32Array);
diff --git a/CryptoLib/src/Math/EC/Rfc8032/ClpEd25519.pas b/CryptoLib/src/Math/EC/Rfc8032/ClpEd25519.pas
index b0f0de82..4aa3551e 100644
--- a/CryptoLib/src/Math/EC/Rfc8032/ClpEd25519.pas
+++ b/CryptoLib/src/Math/EC/Rfc8032/ClpEd25519.pas
@@ -21,7 +21,6 @@
interface
uses
- SyncObjs,
ClpCodec,
ClpDigestUtilities,
ClpBitOperations,
@@ -38,6 +37,7 @@ interface
SDigestSize = 'Digest must produce 64 bytes';
SInvalidOp = 'Invalid point';
SInvalidCtx = 'ctx';
+ SInvalidBufferLength = 'Invalid buffer length';
type
///
@@ -54,6 +54,8 @@ interface
///
TEd25519 = class(TObject)
strict private
+ const
+ DigestSize = 64;
type
TPointAccum = record
private
@@ -131,6 +133,38 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
property Data: TCryptoLibInt32Array read GetData;
end;
+ ///
+ /// Low-level helpers for the expanded private key format (xk =
+ /// Digest(seed), 64 bytes). Bound to a
+ /// owner so overrides apply.
+ ///
+ TExpandedKey = class sealed(TObject)
+ strict private
+ FOwner: TEd25519;
+ procedure CheckExpandedBuffer(const ABuf: TCryptoLibByteArray; AOff: Int32);
+ procedure CheckSeedBuffer(const ABuf: TCryptoLibByteArray; AOff: Int32);
+ private
+ constructor Create(AOwner: TEd25519);
+ public
+ const
+ ExpandedKeySize = DigestSize;
+ procedure ExpandPrivateKey(const ASk: TCryptoLibByteArray; ASkOff: Int32;
+ var AXk: TCryptoLibByteArray; AXkOff: Int32);
+ procedure GeneratePrivateKey(const ARandom: ISecureRandom;
+ var AXk: TCryptoLibByteArray; AXkOff: Int32);
+ procedure GeneratePublicKey(const AXk: TCryptoLibByteArray; AXkOff: Int32;
+ var APk: TCryptoLibByteArray; APkOff: Int32); overload;
+ function GeneratePublicKey(const AXk: TCryptoLibByteArray; AXkOff: Int32): IPublicPoint; overload;
+ procedure Prune(var AXk: TCryptoLibByteArray; AXkOff: Int32);
+ procedure Sign(const AXk: TCryptoLibByteArray; AXkOff: Int32;
+ const AM: TCryptoLibByteArray; AMOff, AMLen: Int32;
+ var ASig: TCryptoLibByteArray; ASigOff: Int32); overload;
+ procedure Sign(const AXk: TCryptoLibByteArray; AXkOff: Int32;
+ const APk: TCryptoLibByteArray; APkOff: Int32;
+ const AM: TCryptoLibByteArray; AMOff, AMLen: Int32;
+ var ASig: TCryptoLibByteArray; ASigOff: Int32); overload;
+ end;
+
strict private
const
CoordUints = 8;
@@ -151,13 +185,11 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
FOrder8_y1, FOrder8_y2: TCryptoLibUInt32Array;
FB_x, FB_y, FB128_x, FB128_y: TCryptoLibInt32Array;
FC_d, FC_d2, FC_d4: TCryptoLibInt32Array;
- FPrecompLock: TCriticalSection;
FPrecompBaseWnaf: TCryptoLibGenericArray;
FPrecompBase128Wnaf: TCryptoLibGenericArray;
FPrecompBaseComb: TCryptoLibInt32Array;
- class procedure Boot; static;
class constructor Create;
- class destructor Destroy;
+ class procedure Precompute; static;
class function CalculateS(const AR, AK, &AS: TCryptoLibByteArray): TCryptoLibByteArray; static;
class function CheckContextVar(ACtx: TCryptoLibByteArray; APhflag: Byte): Boolean; static;
class function CheckPoint(const AP: TPointAccum): Int32; overload; static;
@@ -196,7 +228,11 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
class function PointPrecomputeZ(const AP: TPointAffine; ACount: Int32; var AT: TPointTemp): TCryptoLibInt32Array; overload; static;
class procedure PointPrecomputeZ(const AP: TPointAffine; var APoints: TCryptoLibGenericArray; ACount: Int32; var AT: TPointTemp); overload; static;
class procedure PointSetNeutral(var AP: TPointAccum); static;
- class procedure PruneScalar(const AN: TCryptoLibByteArray; ANOff: Int32; AR: TCryptoLibByteArray); static;
+ class procedure ExpandPrivateKey(const AD: IDigest; const ASk: TCryptoLibByteArray; ASkOff: Int32;
+ const AH: TCryptoLibByteArray; AHOff: Int32); static;
+ class function GeneratePublicPoint(const AH: TCryptoLibByteArray; AHOff: Int32): IPublicPoint; static;
+ class procedure PruneScalar(var AScalar: TCryptoLibByteArray; AScalarOff: Int32); overload; static;
+ class procedure PruneScalar(const AN: TCryptoLibByteArray; ANOff: Int32; AR: TCryptoLibByteArray); overload; static;
class procedure ScalarMult(const AK: TCryptoLibByteArray; const AP: TPointAffine; var AR: TPointAccum); static;
class procedure ScalarMultBase(const AK: TCryptoLibByteArray; var AR: TPointAccum); static;
class procedure ScalarMultBaseEncoded(const AK: TCryptoLibByteArray; AR: TCryptoLibByteArray; AROff: Int32); static;
@@ -222,12 +258,11 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
function CreateDigest(): IDigest; virtual;
public
const
- PrehashSize = 64;
+ PrehashSize = DigestSize;
PublicKeySize = PointBytes;
SecretKeySize = 32;
SignatureSize = PointBytes + ScalarBytes;
- class procedure Precompute; static;
class procedure ScalarMultBaseYZ(const AK: TCryptoLibByteArray; AKOff: Int32; AY, AZ: TCryptoLibInt32Array); static;
class procedure EncodePublicPoint(const APublicPoint: IPublicPoint; APk: TCryptoLibByteArray; APkOff: Int32); static;
@@ -237,6 +272,7 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
class function ValidatePublicKeyPartialExport(const APk: TCryptoLibByteArray; APkOff: Int32): IPublicPoint; static;
function CreatePreHash(): IDigest;
+ function CreateExpandedKey: TExpandedKey;
function GeneratePublicKey(const &AS: TCryptoLibByteArray; ASOff: Int32): IPublicPoint; overload;
procedure GeneratePrivateKey(const ARandom: ISecureRandom; const AK: TCryptoLibByteArray);
procedure GeneratePublicKey(const &AS: TCryptoLibByteArray; ASOff: Int32; APk: TCryptoLibByteArray; APkOff: Int32); overload;
@@ -292,42 +328,31 @@ function TEd25519.TPublicPoint.GetData: TCryptoLibInt32Array;
{ TEd25519 }
class constructor TEd25519.Create;
-begin
- Boot;
-end;
-
-class procedure TEd25519.Boot;
begin
FDom2Prefix := TCryptoLibByteArray.Create($53, $69, $67, $45, $64, $32, $35, $35, $31, $39, $20,
- $6E, $6F, $20, $45, $64, $32, $35, $35, $31, $39, $20, $63, $6F, $6C, $6C, $69, $73, $69,
- $6F, $6E, $73);
+ $6E, $6F, $20, $45, $64, $32, $35, $35, $31, $39, $20, $63, $6F, $6C, $6C, $69, $73, $69,
+ $6F, $6E, $73);
FP := TCryptoLibUInt32Array.Create($FFFFFFED, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $7FFFFFFF);
+ $FFFFFFFF, $FFFFFFFF, $7FFFFFFF);
FOrder8_y1 := TCryptoLibUInt32Array.Create($706A17C7, $4FD84D3D, $760B3CBA, $0F67100D, $FA53202A,
- $C6CC392C, $77FDC74E, $7A03AC92);
+ $C6CC392C, $77FDC74E, $7A03AC92);
FOrder8_y2 := TCryptoLibUInt32Array.Create($8F95E826, $B027B2C2, $89F4C345, $F098EFF2, $05ACDFD5,
- $3933C6D3, $880238B1, $05FC536D);
+ $3933C6D3, $880238B1, $05FC536D);
FB_x := TCryptoLibInt32Array.Create($0325D51A, $018B5823, $007B2C95, $0304A92D, $00D2598E, $01D6DC5C,
- $01388C7F, $013FEC0A, $029E6B72, $0042D26D);
+ $01388C7F, $013FEC0A, $029E6B72, $0042D26D);
FB_y := TCryptoLibInt32Array.Create($02666658, $01999999, $00666666, $03333333, $00CCCCCC, $02666666,
- $01999999, $00666666, $03333333, $00CCCCCC);
+ $01999999, $00666666, $03333333, $00CCCCCC);
FB128_x := TCryptoLibInt32Array.Create($00B7E824, $0011EB98, $003E5FC8, $024E1739, $0131CD0B, $014E29A0,
- $034E6138, $0132C952, $03F9E22F, $00984F5F);
+ $034E6138, $0132C952, $03F9E22F, $00984F5F);
FB128_y := TCryptoLibInt32Array.Create($03F5A66B, $02AF4452, $0049E5BB, $00F28D26, $0121A17C, $02C29C3A,
- $0047AD89, $0087D95F, $0332936E, $00BE5933);
+ $0047AD89, $0087D95F, $0332936E, $00BE5933);
FC_d := TCryptoLibInt32Array.Create($035978A3, $02D37284, $018AB75E, $026A0A0E, $0000E014, $0379E898,
- $01D01E5D, $01E738CC, $03715B7F, $00A406D9);
+ $01D01E5D, $01E738CC, $03715B7F, $00A406D9);
FC_d2 := TCryptoLibInt32Array.Create($02B2F159, $01A6E509, $01156EBD, $00D4141D, $0001C029, $02F3D130,
- $03A03CBB, $01CE7198, $02E2B6FF, $00480DB3);
+ $03A03CBB, $01CE7198, $02E2B6FF, $00480DB3);
FC_d4 := TCryptoLibInt32Array.Create($0165E2B2, $034DCA13, $002ADD7A, $01A8283B, $00038052, $01E7A260,
- $03407977, $019CE331, $01C56DFF, $00901B67);
- FPrecompLock := TCriticalSection.Create;
-end;
-
-class destructor TEd25519.Destroy;
-begin
- FPrecompLock.Free;
- FPrecompLock := nil;
+ $03407977, $019CE331, $01C56DFF, $00901B67);
+ Precompute;
end;
class function TEd25519.CalculateS(const AR, AK, &AS: TCryptoLibByteArray): TCryptoLibByteArray;
@@ -460,7 +485,7 @@ function TEd25519.CreateAndValidateDigest(): IDigest;
LD: IDigest;
begin
LD := CreateDigest();
- if LD.GetDigestSize() <> 64 then
+ if LD.GetDigestSize() <> DigestSize then
raise EInvalidOperationCryptoLibException.CreateRes(@SDigestSize);
Result := LD;
end;
@@ -983,12 +1008,40 @@ class procedure TEd25519.PointSetNeutral(var AP: TPointAccum);
TX25519Field.One(AP.V);
end;
+class procedure TEd25519.PruneScalar(var AScalar: TCryptoLibByteArray; AScalarOff: Int32);
+begin
+ AScalar[AScalarOff] := AScalar[AScalarOff] and $F8;
+ AScalar[AScalarOff + ScalarBytes - 1] := (AScalar[AScalarOff + ScalarBytes - 1] and $7F) or $40;
+end;
+
class procedure TEd25519.PruneScalar(const AN: TCryptoLibByteArray; ANOff: Int32; AR: TCryptoLibByteArray);
begin
System.Move(AN[ANOff], AR[0], ScalarBytes);
- AR[0] := AR[0] and $F8;
- AR[ScalarBytes - 1] := AR[ScalarBytes - 1] and $7F;
- AR[ScalarBytes - 1] := AR[ScalarBytes - 1] or $40;
+ PruneScalar(AR, 0);
+end;
+
+class procedure TEd25519.ExpandPrivateKey(const AD: IDigest; const ASk: TCryptoLibByteArray; ASkOff: Int32;
+ const AH: TCryptoLibByteArray; AHOff: Int32);
+begin
+ AD.BlockUpdate(ASk, ASkOff, SecretKeySize);
+ AD.DoFinal(AH, AHOff);
+end;
+
+class function TEd25519.GeneratePublicPoint(const AH: TCryptoLibByteArray; AHOff: Int32): IPublicPoint;
+var
+ LS: TCryptoLibByteArray;
+ LP: TPointAccum;
+ LQ: TPointAffine;
+begin
+ System.SetLength(LS, ScalarBytes);
+ PruneScalar(AH, AHOff, LS);
+ InitPointAccum(LP);
+ ScalarMultBase(LS, LP);
+ InitPointAffine(LQ);
+ NormalizeToAffine(LP, LQ);
+ if CheckPoint(LQ) = 0 then
+ raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidOp);
+ Result := ExportPoint(LQ);
end;
class procedure TEd25519.ScalarMult(const AK: TCryptoLibByteArray; const AP: TPointAffine; var AR: TPointAccum);
@@ -1032,7 +1085,6 @@ class procedure TEd25519.ScalarMultBase(const AK: TCryptoLibByteArray; var AR: T
LW: UInt32;
LSign, LAbs, LResultSign: Int32;
begin
- Precompute;
System.SetLength(LN, ScalarUints);
TScalar25519.Decode(AK, LN);
TScalar25519.ToSignedDigits(PrecompRange, LN);
@@ -1155,23 +1207,12 @@ class procedure TEd25519.EncodePublicPoint(const APublicPoint: IPublicPoint; APk
function TEd25519.GeneratePublicKey(const &AS: TCryptoLibByteArray; ASOff: Int32): IPublicPoint;
var
LD: IDigest;
- LH, LS: TCryptoLibByteArray;
- LP: TPointAccum;
- LQ: TPointAffine;
+ LH: TCryptoLibByteArray;
begin
LD := CreateAndValidateDigest();
- System.SetLength(LH, 64);
- LD.BlockUpdate(&AS, ASOff, SecretKeySize);
- LD.DoFinal(LH, 0);
- System.SetLength(LS, ScalarBytes);
- PruneScalar(LH, 0, LS);
- InitPointAccum(LP);
- ScalarMultBase(LS, LP);
- InitPointAffine(LQ);
- NormalizeToAffine(LP, LQ);
- if CheckPoint(LQ) = 0 then
- raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidOp);
- Result := ExportPoint(LQ);
+ System.SetLength(LH, DigestSize);
+ ExpandPrivateKey(LD, &AS, ASOff, LH, 0);
+ Result := GeneratePublicPoint(LH, 0);
end;
class function TEd25519.ValidatePublicKeyFull(const APk: TCryptoLibByteArray; APkOff: Int32): Boolean;
@@ -1252,7 +1293,6 @@ class procedure TEd25519.ScalarMultStraus128Var(const ANb: TCryptoLibUInt32Array
System.Assert(System.Length(ANp) = 4);
System.Assert(System.Length(ANq) = 4);
{$ENDIF}
- Precompute();
System.SetLength(LWsB, 256);
System.SetLength(LWsP, 128);
System.SetLength(LWsQ, 128);
@@ -1322,125 +1362,118 @@ class procedure TEd25519.Precompute;
LOff: Int32;
LI: Int32;
begin
- FPrecompLock.Enter;
- try
- if FPrecompBaseComb <> nil then
- Exit;
- LWnafPoints := 1 shl (WnafWidthBase - 2);
- LCombPoints := PrecompBlocks * PrecompPoints;
- LTotalPoints := LWnafPoints * 2 + LCombPoints;
- System.SetLength(LPoints, LTotalPoints);
- InitPointTemp(LT);
- InitPointAffine(LB);
- TX25519Field.Copy(FB_x, 0, LB.X, 0);
- TX25519Field.Copy(FB_y, 0, LB.Y, 0);
- PointPrecompute(LB, LPoints, 0, LWnafPoints, LT);
- InitPointAffine(LB128);
- TX25519Field.Copy(FB128_x, 0, LB128.X, 0);
- TX25519Field.Copy(FB128_y, 0, LB128.Y, 0);
- PointPrecompute(LB128, LPoints, LWnafPoints, LWnafPoints, LT);
- InitPointAccum(LP);
- TX25519Field.Copy(FB_x, 0, LP.X, 0);
- TX25519Field.Copy(FB_y, 0, LP.Y, 0);
- TX25519Field.One(LP.Z);
- TX25519Field.Copy(FB_x, 0, LP.U, 0);
- TX25519Field.Copy(FB_y, 0, LP.V, 0);
- LPointsIndex := LWnafPoints * 2;
- System.SetLength(LToothPowers, PrecompTeeth);
+ LWnafPoints := 1 shl (WnafWidthBase - 2);
+ LCombPoints := PrecompBlocks * PrecompPoints;
+ LTotalPoints := LWnafPoints * 2 + LCombPoints;
+ System.SetLength(LPoints, LTotalPoints);
+ InitPointTemp(LT);
+ InitPointAffine(LB);
+ TX25519Field.Copy(FB_x, 0, LB.X, 0);
+ TX25519Field.Copy(FB_y, 0, LB.Y, 0);
+ PointPrecompute(LB, LPoints, 0, LWnafPoints, LT);
+ InitPointAffine(LB128);
+ TX25519Field.Copy(FB128_x, 0, LB128.X, 0);
+ TX25519Field.Copy(FB128_y, 0, LB128.Y, 0);
+ PointPrecompute(LB128, LPoints, LWnafPoints, LWnafPoints, LT);
+ InitPointAccum(LP);
+ TX25519Field.Copy(FB_x, 0, LP.X, 0);
+ TX25519Field.Copy(FB_y, 0, LP.Y, 0);
+ TX25519Field.One(LP.Z);
+ TX25519Field.Copy(FB_x, 0, LP.U, 0);
+ TX25519Field.Copy(FB_y, 0, LP.V, 0);
+ LPointsIndex := LWnafPoints * 2;
+ System.SetLength(LToothPowers, PrecompTeeth);
+ for LTooth := 0 to PrecompTeeth - 1 do
+ InitPointExtended(LToothPowers[LTooth]);
+ InitPointExtended(LU);
+ for LBlock := 0 to PrecompBlocks - 1 do
+ begin
+ InitPointExtended(LPoints[LPointsIndex]);
for LTooth := 0 to PrecompTeeth - 1 do
- InitPointExtended(LToothPowers[LTooth]);
- InitPointExtended(LU);
- for LBlock := 0 to PrecompBlocks - 1 do
begin
- InitPointExtended(LPoints[LPointsIndex]);
- for LTooth := 0 to PrecompTeeth - 1 do
+ if LTooth = 0 then
+ PointCopy(LP, LPoints[LPointsIndex])
+ else
begin
- if LTooth = 0 then
- PointCopy(LP, LPoints[LPointsIndex])
- else
- begin
- PointCopy(LP, LU);
- PointAdd(LPoints[LPointsIndex], LU, LPoints[LPointsIndex], LT);
- end;
- PointDouble(LP);
- PointCopy(LP, LToothPowers[LTooth]);
- if LBlock + LTooth <> PrecompBlocks + PrecompTeeth - 2 then
- begin
- for LSpacing := 1 to PrecompSpacing - 1 do
- PointDouble(LP);
- end;
+ PointCopy(LP, LU);
+ PointAdd(LPoints[LPointsIndex], LU, LPoints[LPointsIndex], LT);
end;
- TX25519Field.Negate(LPoints[LPointsIndex].X, LPoints[LPointsIndex].X);
- TX25519Field.Negate(LPoints[LPointsIndex].T, LPoints[LPointsIndex].T);
- System.Inc(LPointsIndex);
- for LTooth := 0 to PrecompTeeth - 2 do
+ PointDouble(LP);
+ PointCopy(LP, LToothPowers[LTooth]);
+ if LBlock + LTooth <> PrecompBlocks + PrecompTeeth - 2 then
begin
- LSize := 1 shl LTooth;
- for LJ := 0 to LSize - 1 do
- begin
- InitPointExtended(LPoints[LPointsIndex]);
- PointAdd(LPoints[LPointsIndex - LSize], LToothPowers[LTooth], LPoints[LPointsIndex], LT);
- System.Inc(LPointsIndex);
- end;
+ for LSpacing := 1 to PrecompSpacing - 1 do
+ PointDouble(LP);
end;
end;
- {$IFDEF DEBUG}
- System.Assert(LPointsIndex = LTotalPoints);
- {$ENDIF}
- InvertDoubleZs(LPoints);
- System.SetLength(FPrecompBaseWnaf, LWnafPoints);
- for LI := 0 to LWnafPoints - 1 do
- begin
- InitPointPrecomp(FPrecompBaseWnaf[LI]);
- TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Z, LPoints[LI].X);
- TX25519Field.Mul(LPoints[LI].Y, LPoints[LI].Z, LPoints[LI].Y);
- TX25519Field.Apm(LPoints[LI].Y, LPoints[LI].X, FPrecompBaseWnaf[LI].YpxH, FPrecompBaseWnaf[LI].YmxH);
- TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Y, FPrecompBaseWnaf[LI].Xyd);
- TX25519Field.Mul(FPrecompBaseWnaf[LI].Xyd, FC_d4, FPrecompBaseWnaf[LI].Xyd);
- TX25519Field.Normalize(FPrecompBaseWnaf[LI].YmxH);
- TX25519Field.Normalize(FPrecompBaseWnaf[LI].YpxH);
- TX25519Field.Normalize(FPrecompBaseWnaf[LI].Xyd);
- end;
- System.SetLength(FPrecompBase128Wnaf, LWnafPoints);
- for LI := 0 to LWnafPoints - 1 do
- begin
- InitPointPrecomp(FPrecompBase128Wnaf[LI]);
- LPointsIndex2 := LWnafPoints + LI;
- TX25519Field.Mul(LPoints[LPointsIndex2].X, LPoints[LPointsIndex2].Z, LPoints[LPointsIndex2].X);
- TX25519Field.Mul(LPoints[LPointsIndex2].Y, LPoints[LPointsIndex2].Z, LPoints[LPointsIndex2].Y);
- TX25519Field.Apm(LPoints[LPointsIndex2].Y, LPoints[LPointsIndex2].X, FPrecompBase128Wnaf[LI].YpxH, FPrecompBase128Wnaf[LI].YmxH);
- TX25519Field.Mul(LPoints[LPointsIndex2].X, LPoints[LPointsIndex2].Y, FPrecompBase128Wnaf[LI].Xyd);
- TX25519Field.Mul(FPrecompBase128Wnaf[LI].Xyd, FC_d4, FPrecompBase128Wnaf[LI].Xyd);
- TX25519Field.Normalize(FPrecompBase128Wnaf[LI].YmxH);
- TX25519Field.Normalize(FPrecompBase128Wnaf[LI].YpxH);
- TX25519Field.Normalize(FPrecompBase128Wnaf[LI].Xyd);
- end;
- FPrecompBaseComb := TX25519Field.CreateTable(LCombPoints * 3);
- InitPointPrecomp(LS);
- LOff := 0;
- for LI := LWnafPoints * 2 to LTotalPoints - 1 do
+ TX25519Field.Negate(LPoints[LPointsIndex].X, LPoints[LPointsIndex].X);
+ TX25519Field.Negate(LPoints[LPointsIndex].T, LPoints[LPointsIndex].T);
+ System.Inc(LPointsIndex);
+ for LTooth := 0 to PrecompTeeth - 2 do
begin
- TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Z, LPoints[LI].X);
- TX25519Field.Mul(LPoints[LI].Y, LPoints[LI].Z, LPoints[LI].Y);
- TX25519Field.Apm(LPoints[LI].Y, LPoints[LI].X, LS.YpxH, LS.YmxH);
- TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Y, LS.Xyd);
- TX25519Field.Mul(LS.Xyd, FC_d4, LS.Xyd);
- TX25519Field.Normalize(LS.YmxH);
- TX25519Field.Normalize(LS.YpxH);
- TX25519Field.Normalize(LS.Xyd);
- TX25519Field.Copy(LS.YmxH, 0, FPrecompBaseComb, LOff);
- LOff := LOff + TX25519Field.Size;
- TX25519Field.Copy(LS.YpxH, 0, FPrecompBaseComb, LOff);
- LOff := LOff + TX25519Field.Size;
- TX25519Field.Copy(LS.Xyd, 0, FPrecompBaseComb, LOff);
- LOff := LOff + TX25519Field.Size;
+ LSize := 1 shl LTooth;
+ for LJ := 0 to LSize - 1 do
+ begin
+ InitPointExtended(LPoints[LPointsIndex]);
+ PointAdd(LPoints[LPointsIndex - LSize], LToothPowers[LTooth], LPoints[LPointsIndex], LT);
+ System.Inc(LPointsIndex);
+ end;
end;
- {$IFDEF DEBUG}
- System.Assert(LOff = System.Length(FPrecompBaseComb));
- {$ENDIF}
- finally
- FPrecompLock.Leave;
end;
+ {$IFDEF DEBUG}
+ System.Assert(LPointsIndex = LTotalPoints);
+ {$ENDIF}
+ InvertDoubleZs(LPoints);
+ System.SetLength(FPrecompBaseWnaf, LWnafPoints);
+ for LI := 0 to LWnafPoints - 1 do
+ begin
+ InitPointPrecomp(FPrecompBaseWnaf[LI]);
+ TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Z, LPoints[LI].X);
+ TX25519Field.Mul(LPoints[LI].Y, LPoints[LI].Z, LPoints[LI].Y);
+ TX25519Field.Apm(LPoints[LI].Y, LPoints[LI].X, FPrecompBaseWnaf[LI].YpxH, FPrecompBaseWnaf[LI].YmxH);
+ TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Y, FPrecompBaseWnaf[LI].Xyd);
+ TX25519Field.Mul(FPrecompBaseWnaf[LI].Xyd, FC_d4, FPrecompBaseWnaf[LI].Xyd);
+ TX25519Field.Normalize(FPrecompBaseWnaf[LI].YmxH);
+ TX25519Field.Normalize(FPrecompBaseWnaf[LI].YpxH);
+ TX25519Field.Normalize(FPrecompBaseWnaf[LI].Xyd);
+ end;
+ System.SetLength(FPrecompBase128Wnaf, LWnafPoints);
+ for LI := 0 to LWnafPoints - 1 do
+ begin
+ InitPointPrecomp(FPrecompBase128Wnaf[LI]);
+ LPointsIndex2 := LWnafPoints + LI;
+ TX25519Field.Mul(LPoints[LPointsIndex2].X, LPoints[LPointsIndex2].Z, LPoints[LPointsIndex2].X);
+ TX25519Field.Mul(LPoints[LPointsIndex2].Y, LPoints[LPointsIndex2].Z, LPoints[LPointsIndex2].Y);
+ TX25519Field.Apm(LPoints[LPointsIndex2].Y, LPoints[LPointsIndex2].X, FPrecompBase128Wnaf[LI].YpxH, FPrecompBase128Wnaf[LI].YmxH);
+ TX25519Field.Mul(LPoints[LPointsIndex2].X, LPoints[LPointsIndex2].Y, FPrecompBase128Wnaf[LI].Xyd);
+ TX25519Field.Mul(FPrecompBase128Wnaf[LI].Xyd, FC_d4, FPrecompBase128Wnaf[LI].Xyd);
+ TX25519Field.Normalize(FPrecompBase128Wnaf[LI].YmxH);
+ TX25519Field.Normalize(FPrecompBase128Wnaf[LI].YpxH);
+ TX25519Field.Normalize(FPrecompBase128Wnaf[LI].Xyd);
+ end;
+ FPrecompBaseComb := TX25519Field.CreateTable(LCombPoints * 3);
+ InitPointPrecomp(LS);
+ LOff := 0;
+ for LI := LWnafPoints * 2 to LTotalPoints - 1 do
+ begin
+ TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Z, LPoints[LI].X);
+ TX25519Field.Mul(LPoints[LI].Y, LPoints[LI].Z, LPoints[LI].Y);
+ TX25519Field.Apm(LPoints[LI].Y, LPoints[LI].X, LS.YpxH, LS.YmxH);
+ TX25519Field.Mul(LPoints[LI].X, LPoints[LI].Y, LS.Xyd);
+ TX25519Field.Mul(LS.Xyd, FC_d4, LS.Xyd);
+ TX25519Field.Normalize(LS.YmxH);
+ TX25519Field.Normalize(LS.YpxH);
+ TX25519Field.Normalize(LS.Xyd);
+ TX25519Field.Copy(LS.YmxH, 0, FPrecompBaseComb, LOff);
+ LOff := LOff + TX25519Field.Size;
+ TX25519Field.Copy(LS.YpxH, 0, FPrecompBaseComb, LOff);
+ LOff := LOff + TX25519Field.Size;
+ TX25519Field.Copy(LS.Xyd, 0, FPrecompBaseComb, LOff);
+ LOff := LOff + TX25519Field.Size;
+ end;
+ {$IFDEF DEBUG}
+ System.Assert(LOff = System.Length(FPrecompBaseComb));
+ {$ENDIF}
end;
function TEd25519.CreatePreHash(): IDigest;
@@ -1460,9 +1493,8 @@ procedure TEd25519.GeneratePublicKey(const &AS: TCryptoLibByteArray; ASOff: Int3
LS: TCryptoLibByteArray;
begin
LD := CreateAndValidateDigest();
- System.SetLength(LH, 64);
- LD.BlockUpdate(&AS, ASOff, SecretKeySize);
- LD.DoFinal(LH, 0);
+ System.SetLength(LH, DigestSize);
+ ExpandPrivateKey(LD, &AS, ASOff, LH, 0);
System.SetLength(LS, ScalarBytes);
PruneScalar(LH, 0, LS);
ScalarMultBaseEncoded(LS, APk, APkOff);
@@ -1672,7 +1704,7 @@ function TEd25519.ImplVerify(const ASig: TCryptoLibByteArray; ASigOff: Int32; co
TX25519Field.Negate(LData, LPA.X);
TX25519Field.Copy(LData, TX25519Field.Size, LPA.Y, 0);
LD := CreateAndValidateDigest();
- System.SetLength(LH, 64);
+ System.SetLength(LH, DigestSize);
if (ACtx <> nil) or (APhflag = $01) then
Dom2(LD, APhflag, ACtx);
LD.BlockUpdate(LR, 0, PointBytes);
@@ -1732,7 +1764,7 @@ function TEd25519.ImplVerify(const ASig: TCryptoLibByteArray; ASigOff: Int32; co
Exit(False);
end;
LD := CreateAndValidateDigest();
- System.SetLength(LH, 64);
+ System.SetLength(LH, DigestSize);
if (ACtx <> nil) or (APhflag = $01) then
Dom2(LD, APhflag, ACtx);
LD.BlockUpdate(LR, 0, PointBytes);
@@ -1759,9 +1791,8 @@ procedure TEd25519.ImplSign(const &AS: TCryptoLibByteArray; ASOff: Int32; const
LH, LS, LPk: TCryptoLibByteArray;
begin
LD := CreateAndValidateDigest();
- System.SetLength(LH, 64);
- LD.BlockUpdate(&AS, ASOff, SecretKeySize);
- LD.DoFinal(LH, 0);
+ System.SetLength(LH, DigestSize);
+ ExpandPrivateKey(LD, &AS, ASOff, LH, 0);
System.SetLength(LS, ScalarBytes);
PruneScalar(LH, 0, LS);
System.SetLength(LPk, PointBytes);
@@ -1777,12 +1808,120 @@ procedure TEd25519.ImplSign(const &AS: TCryptoLibByteArray; ASOff: Int32; const
LH, LS: TCryptoLibByteArray;
begin
LD := CreateAndValidateDigest();
- System.SetLength(LH, 64);
- LD.BlockUpdate(&AS, ASOff, SecretKeySize);
- LD.DoFinal(LH, 0);
+ System.SetLength(LH, DigestSize);
+ ExpandPrivateKey(LD, &AS, ASOff, LH, 0);
System.SetLength(LS, ScalarBytes);
PruneScalar(LH, 0, LS);
ImplSign(LD, LH, LS, APk, APkOff, ACtx, APhflag, AM, AMOff, AMLen, ASig, ASigOff);
end;
+function TEd25519.CreateExpandedKey: TExpandedKey;
+begin
+ Result := TExpandedKey.Create(Self);
+end;
+
+{ TEd25519.TExpandedKey }
+
+constructor TEd25519.TExpandedKey.Create(AOwner: TEd25519);
+begin
+ Inherited Create;
+ if AOwner = nil then
+ raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferLength);
+ FOwner := AOwner;
+end;
+
+procedure TEd25519.TExpandedKey.CheckExpandedBuffer(const ABuf: TCryptoLibByteArray; AOff: Int32);
+begin
+ if (ABuf = nil) or (System.Length(ABuf) - AOff < ExpandedKeySize) then
+ raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferLength);
+end;
+
+procedure TEd25519.TExpandedKey.CheckSeedBuffer(const ABuf: TCryptoLibByteArray; AOff: Int32);
+begin
+ if (ABuf = nil) or (System.Length(ABuf) - AOff < SecretKeySize) then
+ raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferLength);
+end;
+
+procedure TEd25519.TExpandedKey.ExpandPrivateKey(const ASk: TCryptoLibByteArray; ASkOff: Int32;
+ var AXk: TCryptoLibByteArray; AXkOff: Int32);
+var
+ LD: IDigest;
+begin
+ CheckSeedBuffer(ASk, ASkOff);
+ CheckExpandedBuffer(AXk, AXkOff);
+ LD := FOwner.CreateAndValidateDigest();
+ TEd25519.ExpandPrivateKey(LD, ASk, ASkOff, AXk, AXkOff);
+end;
+
+procedure TEd25519.TExpandedKey.GeneratePrivateKey(const ARandom: ISecureRandom;
+ var AXk: TCryptoLibByteArray; AXkOff: Int32);
+var
+ LSk: TCryptoLibByteArray;
+begin
+ CheckExpandedBuffer(AXk, AXkOff);
+ System.SetLength(LSk, SecretKeySize);
+ FOwner.GeneratePrivateKey(ARandom, LSk);
+ ExpandPrivateKey(LSk, 0, AXk, AXkOff);
+end;
+
+procedure TEd25519.TExpandedKey.GeneratePublicKey(const AXk: TCryptoLibByteArray; AXkOff: Int32;
+ var APk: TCryptoLibByteArray; APkOff: Int32);
+var
+ LS: TCryptoLibByteArray;
+begin
+ CheckExpandedBuffer(AXk, AXkOff);
+ if (APk = nil) or (System.Length(APk) - APkOff < PublicKeySize) then
+ raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferLength);
+ System.SetLength(LS, ScalarBytes);
+ PruneScalar(AXk, AXkOff, LS);
+ ScalarMultBaseEncoded(LS, APk, APkOff);
+end;
+
+function TEd25519.TExpandedKey.GeneratePublicKey(const AXk: TCryptoLibByteArray; AXkOff: Int32): IPublicPoint;
+begin
+ CheckExpandedBuffer(AXk, AXkOff);
+ Result := GeneratePublicPoint(AXk, AXkOff);
+end;
+
+procedure TEd25519.TExpandedKey.Prune(var AXk: TCryptoLibByteArray; AXkOff: Int32);
+begin
+ CheckExpandedBuffer(AXk, AXkOff);
+ PruneScalar(AXk, AXkOff);
+end;
+
+procedure TEd25519.TExpandedKey.Sign(const AXk: TCryptoLibByteArray; AXkOff: Int32;
+ const AM: TCryptoLibByteArray; AMOff, AMLen: Int32;
+ var ASig: TCryptoLibByteArray; ASigOff: Int32);
+var
+ LPk: TCryptoLibByteArray;
+begin
+ CheckExpandedBuffer(AXk, AXkOff);
+ System.SetLength(LPk, PublicKeySize);
+ GeneratePublicKey(AXk, AXkOff, LPk, 0);
+ Sign(AXk, AXkOff, LPk, 0, AM, AMOff, AMLen, ASig, ASigOff);
+end;
+
+procedure TEd25519.TExpandedKey.Sign(const AXk: TCryptoLibByteArray; AXkOff: Int32;
+ const APk: TCryptoLibByteArray; APkOff: Int32;
+ const AM: TCryptoLibByteArray; AMOff, AMLen: Int32;
+ var ASig: TCryptoLibByteArray; ASigOff: Int32);
+var
+ LD: IDigest;
+ LH, LS: TCryptoLibByteArray;
+ LNullCtx: TCryptoLibByteArray;
+begin
+ CheckExpandedBuffer(AXk, AXkOff);
+ if (APk = nil) or (System.Length(APk) - APkOff < PublicKeySize) then
+ raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferLength);
+ if (ASig = nil) or (System.Length(ASig) - ASigOff < SignatureSize) then
+ raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferLength);
+ LD := FOwner.CreateAndValidateDigest();
+ System.SetLength(LH, DigestSize);
+ System.Move(AXk[AXkOff], LH[0], DigestSize);
+ System.SetLength(LS, ScalarBytes);
+ PruneScalar(LH, 0, LS);
+ LNullCtx := nil;
+ FOwner.ImplSign(LD, LH, LS, APk, APkOff, LNullCtx, Byte($00), AM, AMOff, AMLen, ASig, ASigOff);
+end;
+
end.
diff --git a/CryptoLib/src/Math/EC/Rfc8032/ClpEd448.pas b/CryptoLib/src/Math/EC/Rfc8032/ClpEd448.pas
index 4ea915e4..32062abe 100644
--- a/CryptoLib/src/Math/EC/Rfc8032/ClpEd448.pas
+++ b/CryptoLib/src/Math/EC/Rfc8032/ClpEd448.pas
@@ -21,7 +21,6 @@
interface
uses
- SyncObjs,
ClpDigestUtilities,
ClpCodec,
ClpBitOperations,
@@ -98,6 +97,7 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
PointBytes = Int32(CoordUints * 4 + 1);
ScalarUints = Int32(14);
ScalarBytes = Int32(ScalarUints * 4 + 1);
+ XofSize = ScalarBytes * 2;
C_d = UInt32(39081);
WnafWidth225 = Int32(5);
WnafWidthBase = Int32(7);
@@ -111,13 +111,11 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
FDom4Prefix: TCryptoLibByteArray;
FP: TCryptoLibUInt32Array;
FB_x, FB_y, FB225_x, FB225_y: TCryptoLibUInt32Array;
- FPrecompLock: TCriticalSection;
FPrecompBaseWnaf: TCryptoLibGenericArray;
FPrecompBase225Wnaf: TCryptoLibGenericArray;
FPrecompBaseComb: TCryptoLibUInt32Array;
- class procedure Boot; static;
class constructor Create;
- class destructor Destroy;
+ class procedure Precompute; static;
class function CalculateS(const AR, AK, &AS: TCryptoLibByteArray): TCryptoLibByteArray; static;
class function CheckContextVar(const ACtx: TCryptoLibByteArray): Boolean; static;
class function CheckPoint(var AP: TPointAffine): Int32; overload; static;
@@ -195,8 +193,6 @@ TPublicPoint = class sealed(TInterfacedObject, IPublicPoint)
function GeneratePublicKey(const ASk: TCryptoLibByteArray; ASkOff: Int32): IPublicPoint; overload;
- class procedure Precompute; static;
-
class procedure ScalarMultBaseXY(const AK: TCryptoLibByteArray; AKOff: Int32;
const AX, AY: TCryptoLibUInt32Array); static;
@@ -266,17 +262,6 @@ function TEd448.TPublicPoint.GetData: TCryptoLibUInt32Array;
{ TEd448 }
class constructor TEd448.Create;
-begin
- FPrecompLock := TCriticalSection.Create;
- Boot;
-end;
-
-class destructor TEd448.Destroy;
-begin
- FPrecompLock.Free;
-end;
-
-class procedure TEd448.Boot;
begin
PrehashSize := 64;
PublicKeySize := PointBytes;
@@ -286,22 +271,23 @@ class procedure TEd448.Boot;
FDom4Prefix := TCryptoLibByteArray.Create($53, $69, $67, $45, $64, $34, $34, $38);
FP := TCryptoLibUInt32Array.Create($FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFE, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF);
FB_x := TCryptoLibUInt32Array.Create($070CC05E, $026A82BC, $00938E26, $080E18B0,
- $0511433B, $0F72AB66, $0412AE1A, $0A3D3A46, $0A6DE324, $00F1767E, $04657047,
- $036DA9E1, $05A622BF, $0ED221D1, $066BED0D, $04F1970C);
+ $0511433B, $0F72AB66, $0412AE1A, $0A3D3A46, $0A6DE324, $00F1767E, $04657047,
+ $036DA9E1, $05A622BF, $0ED221D1, $066BED0D, $04F1970C);
FB_y := TCryptoLibUInt32Array.Create($0230FA14, $008795BF, $07C8AD98, $0132C4ED,
- $09C4FDBD, $01CE67C3, $073AD3FF, $005A0C2D, $07789C1E, $0A398408, $0A73736C,
- $0C7624BE, $003756C9, $02488762, $016EB6BC, $0693F467);
+ $09C4FDBD, $01CE67C3, $073AD3FF, $005A0C2D, $07789C1E, $0A398408, $0A73736C,
+ $0C7624BE, $003756C9, $02488762, $016EB6BC, $0693F467);
FB225_x := TCryptoLibUInt32Array.Create($06909EE2, $01D7605C, $0995EC8A, $0FC4D970,
- $0CF2B361, $02D82E9D, $01225F55, $007F0EF6, $0AEE9C55, $0A240C13, $05627B54,
- $0D449D1E, $03A44575, $007164A7, $0BD4BD71, $061A15FD);
+ $0CF2B361, $02D82E9D, $01225F55, $007F0EF6, $0AEE9C55, $0A240C13, $05627B54,
+ $0D449D1E, $03A44575, $007164A7, $0BD4BD71, $061A15FD);
FB225_y := TCryptoLibUInt32Array.Create($0D3A9FE4, $030696B9, $07E7E326, $068308C7,
- $0CE0B8C8, $03AC222B, $0304DB8E, $083EE319, $05E5DB0B, $0ECA503B, $0B1C6539,
- $078A8DCE, $02D256BC, $04A8B05E, $0BD9FD57, $0A1C3CB8);
+ $0CE0B8C8, $03AC222B, $0304DB8E, $083EE319, $05E5DB0B, $0ECA503B, $0B1C6539,
+ $078A8DCE, $02D256BC, $04A8B05E, $0BD9FD57, $0A1C3CB8);
+ Precompute;
end;
class function TEd448.CalculateS(const AR, AK, &AS: TCryptoLibByteArray): TCryptoLibByteArray;
@@ -319,7 +305,7 @@ class function TEd448.CalculateS(const AR, AK, &AS: TCryptoLibByteArray): TCrypt
TNat.MulAddTo(ScalarUints, LU, LV, LT);
- System.SetLength(LResult, ScalarBytes * 2);
+ System.SetLength(LResult, XofSize);
TCodec.Encode32(LT, 0, System.Length(LT), LResult, 0);
Result := TScalar448.Reduce912(LResult);
end;
@@ -945,116 +931,108 @@ class procedure TEd448.Precompute;
LToothPowers: TCryptoLibGenericArray;
LBlock, LTooth, LSpacing, LSize, LJ, LI, LOff: Int32;
begin
- FPrecompLock.Acquire;
- try
- if FPrecompBaseComb <> nil then
- Exit;
+ LWnafPoints := 1 shl (WnafWidthBase - 2);
+ LCombPoints := PrecompBlocks * PrecompPoints;
+ LTotalPoints := LWnafPoints * 2 + LCombPoints;
- LWnafPoints := 1 shl (WnafWidthBase - 2);
- LCombPoints := PrecompBlocks * PrecompPoints;
- LTotalPoints := LWnafPoints * 2 + LCombPoints;
+ System.SetLength(LPoints, LTotalPoints);
+ InitPointTemp(LT);
- System.SetLength(LPoints, LTotalPoints);
- InitPointTemp(LT);
+ InitPointAffine(LB);
+ TX448Field.Copy(FB_x, 0, LB.X, 0);
+ TX448Field.Copy(FB_y, 0, LB.Y, 0);
- InitPointAffine(LB);
- TX448Field.Copy(FB_x, 0, LB.X, 0);
- TX448Field.Copy(FB_y, 0, LB.Y, 0);
+ PointPrecompute(LB, LPoints, 0, LWnafPoints, LT);
- PointPrecompute(LB, LPoints, 0, LWnafPoints, LT);
+ InitPointAffine(LB225);
+ TX448Field.Copy(FB225_x, 0, LB225.X, 0);
+ TX448Field.Copy(FB225_y, 0, LB225.Y, 0);
- InitPointAffine(LB225);
- TX448Field.Copy(FB225_x, 0, LB225.X, 0);
- TX448Field.Copy(FB225_y, 0, LB225.Y, 0);
+ PointPrecompute(LB225, LPoints, LWnafPoints, LWnafPoints, LT);
- PointPrecompute(LB225, LPoints, LWnafPoints, LWnafPoints, LT);
+ InitPointProjective(LP);
+ PointCopy(LB, LP);
- InitPointProjective(LP);
- PointCopy(LB, LP);
+ LPointsIndex := LWnafPoints * 2;
+ System.SetLength(LToothPowers, PrecompTeeth);
+ for LTooth := 0 to PrecompTeeth - 1 do
+ begin
+ InitPointProjective(LToothPowers[LTooth]);
+ end;
+
+ for LBlock := 0 to PrecompBlocks - 1 do
+ begin
+ InitPointProjective(LPoints[LPointsIndex]);
- LPointsIndex := LWnafPoints * 2;
- System.SetLength(LToothPowers, PrecompTeeth);
for LTooth := 0 to PrecompTeeth - 1 do
begin
- InitPointProjective(LToothPowers[LTooth]);
- end;
+ if LTooth = 0 then
+ PointCopy(LP, LPoints[LPointsIndex])
+ else
+ PointAdd(LP, LPoints[LPointsIndex], LT);
- for LBlock := 0 to PrecompBlocks - 1 do
- begin
- InitPointProjective(LPoints[LPointsIndex]);
+ PointDouble(LP, LT);
+ PointCopy(LP, LToothPowers[LTooth]);
- for LTooth := 0 to PrecompTeeth - 1 do
+ if LBlock + LTooth <> PrecompBlocks + PrecompTeeth - 2 then
begin
- if LTooth = 0 then
- PointCopy(LP, LPoints[LPointsIndex])
- else
- PointAdd(LP, LPoints[LPointsIndex], LT);
-
- PointDouble(LP, LT);
- PointCopy(LP, LToothPowers[LTooth]);
-
- if LBlock + LTooth <> PrecompBlocks + PrecompTeeth - 2 then
+ for LSpacing := 1 to PrecompSpacing - 1 do
begin
- for LSpacing := 1 to PrecompSpacing - 1 do
- begin
- PointDouble(LP, LT);
- end;
+ PointDouble(LP, LT);
end;
end;
+ end;
- Inc(LPointsIndex);
+ Inc(LPointsIndex);
- TX448Field.Negate(LPoints[LPointsIndex - 1].X, LPoints[LPointsIndex - 1].X);
+ TX448Field.Negate(LPoints[LPointsIndex - 1].X, LPoints[LPointsIndex - 1].X);
- for LTooth := 0 to PrecompTeeth - 2 do
+ for LTooth := 0 to PrecompTeeth - 2 do
+ begin
+ LSize := 1 shl LTooth;
+ for LJ := 0 to LSize - 1 do
begin
- LSize := 1 shl LTooth;
- for LJ := 0 to LSize - 1 do
- begin
- InitPointProjective(LPoints[LPointsIndex]);
- PointCopy(LPoints[LPointsIndex - LSize], LPoints[LPointsIndex]);
- PointAdd(LToothPowers[LTooth], LPoints[LPointsIndex], LT);
- Inc(LPointsIndex);
- end;
+ InitPointProjective(LPoints[LPointsIndex]);
+ PointCopy(LPoints[LPointsIndex - LSize], LPoints[LPointsIndex]);
+ PointAdd(LToothPowers[LTooth], LPoints[LPointsIndex], LT);
+ Inc(LPointsIndex);
end;
end;
+ end;
- InvertZs(LPoints);
+ InvertZs(LPoints);
- System.SetLength(FPrecompBaseWnaf, LWnafPoints);
- for LI := 0 to LWnafPoints - 1 do
- begin
- InitPointAffine(FPrecompBaseWnaf[LI]);
- TX448Field.Mul(LPoints[LI].X, LPoints[LI].Z, FPrecompBaseWnaf[LI].X);
- TX448Field.Normalize(FPrecompBaseWnaf[LI].X);
- TX448Field.Mul(LPoints[LI].Y, LPoints[LI].Z, FPrecompBaseWnaf[LI].Y);
- TX448Field.Normalize(FPrecompBaseWnaf[LI].Y);
- end;
+ System.SetLength(FPrecompBaseWnaf, LWnafPoints);
+ for LI := 0 to LWnafPoints - 1 do
+ begin
+ InitPointAffine(FPrecompBaseWnaf[LI]);
+ TX448Field.Mul(LPoints[LI].X, LPoints[LI].Z, FPrecompBaseWnaf[LI].X);
+ TX448Field.Normalize(FPrecompBaseWnaf[LI].X);
+ TX448Field.Mul(LPoints[LI].Y, LPoints[LI].Z, FPrecompBaseWnaf[LI].Y);
+ TX448Field.Normalize(FPrecompBaseWnaf[LI].Y);
+ end;
- System.SetLength(FPrecompBase225Wnaf, LWnafPoints);
- for LI := 0 to LWnafPoints - 1 do
- begin
- InitPointAffine(FPrecompBase225Wnaf[LI]);
- TX448Field.Mul(LPoints[LWnafPoints + LI].X, LPoints[LWnafPoints + LI].Z, FPrecompBase225Wnaf[LI].X);
- TX448Field.Normalize(FPrecompBase225Wnaf[LI].X);
- TX448Field.Mul(LPoints[LWnafPoints + LI].Y, LPoints[LWnafPoints + LI].Z, FPrecompBase225Wnaf[LI].Y);
- TX448Field.Normalize(FPrecompBase225Wnaf[LI].Y);
- end;
+ System.SetLength(FPrecompBase225Wnaf, LWnafPoints);
+ for LI := 0 to LWnafPoints - 1 do
+ begin
+ InitPointAffine(FPrecompBase225Wnaf[LI]);
+ TX448Field.Mul(LPoints[LWnafPoints + LI].X, LPoints[LWnafPoints + LI].Z, FPrecompBase225Wnaf[LI].X);
+ TX448Field.Normalize(FPrecompBase225Wnaf[LI].X);
+ TX448Field.Mul(LPoints[LWnafPoints + LI].Y, LPoints[LWnafPoints + LI].Z, FPrecompBase225Wnaf[LI].Y);
+ TX448Field.Normalize(FPrecompBase225Wnaf[LI].Y);
+ end;
- FPrecompBaseComb := TX448Field.CreateTable(LCombPoints * 2);
- LOff := 0;
- for LI := LWnafPoints * 2 to LTotalPoints - 1 do
- begin
- TX448Field.Mul(LPoints[LI].X, LPoints[LI].Z, LPoints[LI].X);
- TX448Field.Normalize(LPoints[LI].X);
- TX448Field.Mul(LPoints[LI].Y, LPoints[LI].Z, LPoints[LI].Y);
- TX448Field.Normalize(LPoints[LI].Y);
+ FPrecompBaseComb := TX448Field.CreateTable(LCombPoints * 2);
+ LOff := 0;
+ for LI := LWnafPoints * 2 to LTotalPoints - 1 do
+ begin
+ TX448Field.Mul(LPoints[LI].X, LPoints[LI].Z, LPoints[LI].X);
+ TX448Field.Normalize(LPoints[LI].X);
+ TX448Field.Mul(LPoints[LI].Y, LPoints[LI].Z, LPoints[LI].Y);
+ TX448Field.Normalize(LPoints[LI].Y);
- TX448Field.Copy(LPoints[LI].X, 0, FPrecompBaseComb, LOff); Inc(LOff, TX448Field.Size);
- TX448Field.Copy(LPoints[LI].Y, 0, FPrecompBaseComb, LOff); Inc(LOff, TX448Field.Size);
- end;
- finally
- FPrecompLock.Release;
+ TX448Field.Copy(LPoints[LI].X, 0, FPrecompBaseComb, LOff); Inc(LOff, TX448Field.Size);
+ TX448Field.Copy(LPoints[LI].Y, 0, FPrecompBaseComb, LOff); Inc(LOff, TX448Field.Size);
end;
end;
@@ -1111,8 +1089,6 @@ class procedure TEd448.ScalarMultBase(const AK: TCryptoLibByteArray; var AR: TPo
LW, LTBit: UInt32;
LSign, LAbs: Int32;
begin
- Precompute;
-
System.SetLength(LN, ScalarUints + 1);
TScalar448.Decode(AK, LN);
TScalar448.ToSignedDigits(PrecompRange, LN, LN);
@@ -1229,8 +1205,6 @@ class procedure TEd448.ScalarMultStraus225Var(const ANb: TCryptoLibUInt32Array;
LTp, LTq: TCryptoLibGenericArray;
LT: TPointTemp;
begin
- Precompute;
-
System.SetLength(LWs_b, 450);
System.SetLength(LWs_p, 225);
System.SetLength(LWs_q, 225);
@@ -1332,7 +1306,7 @@ procedure TEd448.ImplSign(const ASk: TCryptoLibByteArray; ASkOff: Int32; const A
raise EArgumentCryptoLibException.CreateRes(@SInvalidCtx);
LD := CreateAndValidateXof();
- System.SetLength(LH, ScalarBytes * 2);
+ System.SetLength(LH, XofSize);
LD.BlockUpdate(ASk, ASkOff, SecretKeySize);
LD.OutputFinal(LH, 0, System.Length(LH));
@@ -1356,7 +1330,7 @@ procedure TEd448.ImplSign(const ASk: TCryptoLibByteArray; ASkOff: Int32; const A
raise EArgumentCryptoLibException.CreateRes(@SInvalidCtx);
LD := CreateAndValidateXof();
- System.SetLength(LH, ScalarBytes * 2);
+ System.SetLength(LH, XofSize);
LD.BlockUpdate(ASk, ASkOff, SecretKeySize);
LD.OutputFinal(LH, 0, System.Length(LH));
@@ -1419,7 +1393,7 @@ function TEd448.ImplVerify(const ASig: TCryptoLibByteArray; ASigOff: Int32;
end;
LD := CreateAndValidateXof();
- System.SetLength(LH, ScalarBytes * 2);
+ System.SetLength(LH, XofSize);
Dom4(LD, APhflag, ACtx);
LD.BlockUpdate(LR, 0, PointBytes);
@@ -1491,7 +1465,7 @@ function TEd448.ImplVerify(const ASig: TCryptoLibByteArray; ASigOff: Int32;
EncodePublicPoint(APublicPoint, LA, 0);
LD := CreateAndValidateXof();
- System.SetLength(LH, ScalarBytes * 2);
+ System.SetLength(LH, XofSize);
Dom4(LD, APhflag, ACtx);
LD.BlockUpdate(LR, 0, PointBytes);
@@ -1531,7 +1505,7 @@ procedure TEd448.GeneratePublicKey(const ASk: TCryptoLibByteArray; ASkOff: Int32
LH, LS: TCryptoLibByteArray;
begin
LD := CreateAndValidateXof();
- System.SetLength(LH, ScalarBytes * 2);
+ System.SetLength(LH, XofSize);
LD.BlockUpdate(ASk, ASkOff, SecretKeySize);
LD.OutputFinal(LH, 0, System.Length(LH));
@@ -1548,7 +1522,7 @@ function TEd448.GeneratePublicKey(const ASk: TCryptoLibByteArray; ASkOff: Int32)
LQ: TPointAffine;
begin
LD := CreateAndValidateXof();
- System.SetLength(LH, ScalarBytes * 2);
+ System.SetLength(LH, XofSize);
LD.BlockUpdate(ASk, ASkOff, SecretKeySize);
LD.OutputFinal(LH, 0, System.Length(LH));
diff --git a/CryptoLib/src/Math/EC/Rfc8032/ClpScalar25519.pas b/CryptoLib/src/Math/EC/Rfc8032/ClpScalar25519.pas
index f42d8500..bee0d967 100644
--- a/CryptoLib/src/Math/EC/Rfc8032/ClpScalar25519.pas
+++ b/CryptoLib/src/Math/EC/Rfc8032/ClpScalar25519.pas
@@ -44,7 +44,6 @@ TScalar25519 = class sealed
L4 = $000014DF;
class var
FL, FLsq: TCryptoLibUInt32Array;
- class procedure Boot; static;
class constructor Create;
public
class function CheckVar(const &AS: TCryptoLibByteArray; AN: TCryptoLibUInt32Array): Boolean; static;
@@ -64,17 +63,12 @@ TScalar25519 = class sealed
implementation
class constructor TScalar25519.Create;
-begin
- Boot;
-end;
-
-class procedure TScalar25519.Boot;
begin
FL := TCryptoLibUInt32Array.Create($5CF5D3ED, $5812631A, $A2F79CD6, $14DEF9DE,
- $00000000, $00000000, $00000000, $10000000);
+ $00000000, $00000000, $00000000, $10000000);
FLsq := TCryptoLibUInt32Array.Create($AB128969, $E2EDF685, $2298A31D, $68039276,
- $D217F5BE, $3DCEEC73, $1B7C309A, $A1B39941, $4B9EBA7D, $CB024C63, $D45EF39A,
- $029BDF3B, $00000000, $00000000, $00000000, $01000000);
+ $D217F5BE, $3DCEEC73, $1B7C309A, $A1B39941, $4B9EBA7D, $CB024C63, $D45EF39A,
+ $029BDF3B, $00000000, $00000000, $00000000, $01000000);
end;
class function TScalar25519.CheckVar(const &AS: TCryptoLibByteArray; AN: TCryptoLibUInt32Array): Boolean;
diff --git a/CryptoLib/src/Math/EC/Rfc8032/ClpScalar448.pas b/CryptoLib/src/Math/EC/Rfc8032/ClpScalar448.pas
index 28e08c69..b0b6b499 100644
--- a/CryptoLib/src/Math/EC/Rfc8032/ClpScalar448.pas
+++ b/CryptoLib/src/Math/EC/Rfc8032/ClpScalar448.pas
@@ -58,7 +58,6 @@ TScalar448 = class sealed
L4_7 = Int32($20CD7705);
class var
FL, FLSq: TCryptoLibUInt32Array;
- class procedure Boot; static;
class constructor Create;
public
class function CheckVar(const &AS: TCryptoLibByteArray;
@@ -86,20 +85,15 @@ implementation
{ TScalar448 }
class constructor TScalar448.Create;
-begin
- Boot;
-end;
-
-class procedure TScalar448.Boot;
begin
FL := TCryptoLibUInt32Array.Create($AB5844F3, $2378C292, $8DC58F55, $216CC272,
- $AED63690, $C44EDB49, $7CCA23E9, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $3FFFFFFF);
+ $AED63690, $C44EDB49, $7CCA23E9, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $3FFFFFFF);
FLSq := TCryptoLibUInt32Array.Create($1BA1FEA9, $C1ADFBB8, $49E0A8B2, $B91BF537,
- $E764D815, $4525492B, $A2B8716D, $4AE17CF6, $BA3C47C4, $F1A9CC14,
- $7E4D070A, $92052BCB, $9F823B72, $C3402A93, $55AC2279, $91BC6149,
- $46E2C7AA, $10B66139, $D76B1B48, $E2276DA4, $BE6511F4, $FFFFFFFF,
- $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $0FFFFFFF);
+ $E764D815, $4525492B, $A2B8716D, $4AE17CF6, $BA3C47C4, $F1A9CC14,
+ $7E4D070A, $92052BCB, $9F823B72, $C3402A93, $55AC2279, $91BC6149,
+ $46E2C7AA, $10B66139, $D76B1B48, $E2276DA4, $BE6511F4, $FFFFFFFF,
+ $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $0FFFFFFF);
end;
class function TScalar448.CheckVar(const &AS: TCryptoLibByteArray;
diff --git a/CryptoLib/src/Math/Raw/ClpNat.pas b/CryptoLib/src/Math/Raw/ClpNat.pas
index d9ac339c..f5cae380 100644
--- a/CryptoLib/src/Math/Raw/ClpNat.pas
+++ b/CryptoLib/src/Math/Raw/ClpNat.pas
@@ -144,6 +144,10 @@ TNat = class sealed
class function ShiftUpBits64(ALen: Int32; AZ: TCryptoLibUInt64Array; AZOff: Int32; ABits: Int32; AC: UInt64): UInt64; overload; static;
class function ShiftUpBits64(ALen: Int32; const AX: TCryptoLibUInt64Array; ABits: Int32; AC: UInt64; AZ: TCryptoLibUInt64Array): UInt64; overload; static;
class function ShiftUpBits64(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32; ABits: Int32; AC: UInt64; AZ: TCryptoLibUInt64Array; AZOff: Int32): UInt64; overload; static;
+ class function ShiftUpBitsXor64(ALen: Int32; const AX: TCryptoLibUInt64Array; ABits: Int32; AC: UInt64;
+ const AY: TCryptoLibUInt64Array; AZ: TCryptoLibUInt64Array): UInt64; overload; static;
+ class function ShiftUpBitsXor64(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32; ABits: Int32; AC: UInt64;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; AZ: TCryptoLibUInt64Array; AZOff: Int32): UInt64; overload; static;
class procedure Square(ALen: Int32; const AX: TCryptoLibUInt32Array; AZz: TCryptoLibUInt32Array); overload; static;
class procedure Square(ALen: Int32; const AX: TCryptoLibUInt32Array; AXOff: Int32; AZz: TCryptoLibUInt32Array; AZzOff: Int32); overload; static;
class function SquareWordAddTo(const AX: TCryptoLibUInt32Array; AXPos: Int32; AZ: TCryptoLibUInt32Array): UInt32; overload; static;
@@ -167,6 +171,8 @@ TNat = class sealed
class function SubWordFrom(ALen: Int32; AX: UInt32; AZ: TCryptoLibUInt32Array): Int32; overload; static;
class function SubWordFrom(ALen: Int32; AX: UInt32; AZ: TCryptoLibUInt32Array; AZOff: Int32): Int32; overload; static;
class function ToBigInteger(ALen: Int32; const AX: TCryptoLibUInt32Array): TBigInteger; static;
+ class function ToBigInteger64(ALen: Int32; const AX: TCryptoLibUInt64Array): TBigInteger; overload; static;
+ class function ToBigInteger64(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): TBigInteger; overload; static;
class procedure &Xor(ALen: Int32; const AX: TCryptoLibUInt32Array; const AY: TCryptoLibUInt32Array; AZ: TCryptoLibUInt32Array); overload; static;
class procedure &Xor(ALen: Int32; const AX: TCryptoLibUInt32Array; AXOff: Int32; const AY: TCryptoLibUInt32Array; AYOff: Int32; AZ: TCryptoLibUInt32Array; AZOff: Int32); overload; static;
class procedure &Xor(ALen: Int32; const AX: TCryptoLibUInt32Array; AY: UInt32; AZ: TCryptoLibUInt32Array); overload; static;
@@ -2139,6 +2145,59 @@ class function TNat.ShiftUpBits64(ALen: Int32; const AX: TCryptoLibUInt64Array;
Result := TBitOperations.NegativeRightShift64(AC, -ABits);
end;
+class function TNat.ShiftUpBitsXor64(ALen: Int32; const AX: TCryptoLibUInt64Array; ABits: Int32; AC: UInt64;
+ const AY: TCryptoLibUInt64Array; AZ: TCryptoLibUInt64Array): UInt64;
+begin
+ Result := ShiftUpBitsXor64(ALen, AX, 0, ABits, AC, AY, 0, AZ, 0);
+end;
+
+class function TNat.ShiftUpBitsXor64(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32; ABits: Int32; AC: UInt64;
+ const AY: TCryptoLibUInt64Array; AYOff: Int32; AZ: TCryptoLibUInt64Array; AZOff: Int32): UInt64;
+var
+ LI: Int32;
+ LX0: UInt64;
+ LX1: UInt64;
+ LX2: UInt64;
+ LX3: UInt64;
+ LXi: UInt64;
+ LY0: UInt64;
+ LY1: UInt64;
+ LY2: UInt64;
+ LY3: UInt64;
+ LYi: UInt64;
+begin
+ LI := 0;
+ {$IFDEF DEBUG}
+ System.Assert((ABits > 0) and (ABits < 64));
+ {$ENDIF}
+ while LI <= ALen - 4 do
+ begin
+ LX0 := AX[AXOff + LI + 0];
+ LX1 := AX[AXOff + LI + 1];
+ LX2 := AX[AXOff + LI + 2];
+ LX3 := AX[AXOff + LI + 3];
+ LY0 := AY[AYOff + LI + 0];
+ LY1 := AY[AYOff + LI + 1];
+ LY2 := AY[AYOff + LI + 2];
+ LY3 := AY[AYOff + LI + 3];
+ AZ[AZOff + LI + 0] := ((LX0 shl ABits) or TBitOperations.NegativeRightShift64(AC, -ABits)) xor LY0;
+ AZ[AZOff + LI + 1] := ((LX1 shl ABits) or TBitOperations.NegativeRightShift64(LX0, -ABits)) xor LY1;
+ AZ[AZOff + LI + 2] := ((LX2 shl ABits) or TBitOperations.NegativeRightShift64(LX1, -ABits)) xor LY2;
+ AZ[AZOff + LI + 3] := ((LX3 shl ABits) or TBitOperations.NegativeRightShift64(LX2, -ABits)) xor LY3;
+ AC := LX3;
+ LI := LI + 4;
+ end;
+ while LI < ALen do
+ begin
+ LXi := AX[AXOff + LI];
+ LYi := AY[AYOff + LI];
+ AZ[AZOff + LI] := ((LXi shl ABits) or TBitOperations.NegativeRightShift64(AC, -ABits)) xor LYi;
+ AC := LXi;
+ System.Inc(LI);
+ end;
+ Result := TBitOperations.NegativeRightShift64(AC, -ABits);
+end;
+
class procedure TNat.Square(ALen: Int32; const AX: TCryptoLibUInt32Array; AZz: TCryptoLibUInt32Array);
var
LExtLen: Int32;
@@ -2646,6 +2705,29 @@ class function TNat.ToBigInteger(ALen: Int32; const AX: TCryptoLibUInt32Array):
Result := TBigInteger.Create(1, LBs);
end;
+class function TNat.ToBigInteger64(ALen: Int32; const AX: TCryptoLibUInt64Array): TBigInteger;
+begin
+ Result := ToBigInteger64(ALen, AX, 0);
+end;
+
+class function TNat.ToBigInteger64(ALen: Int32; const AX: TCryptoLibUInt64Array; AXOff: Int32): TBigInteger;
+var
+ LBs: TCryptoLibByteArray;
+ LXPos: Int32;
+ LBsPos: Int32;
+begin
+ SetLength(LBs, ALen shl 3);
+ LXPos := ALen - 1;
+ LBsPos := 0;
+ while LXPos >= 0 do
+ begin
+ TPack.UInt64_To_BE(AX[AXOff + LXPos], LBs, LBsPos);
+ LBsPos := LBsPos + 8;
+ System.Dec(LXPos);
+ end;
+ Result := TBigInteger.Create(1, LBs);
+end;
+
class procedure TNat.&Xor(ALen: Int32; const AX: TCryptoLibUInt32Array; const AY: TCryptoLibUInt32Array; AZ: TCryptoLibUInt32Array);
var
LI: Int32;
diff --git a/CryptoLib/src/Misc/ClpBinaryPrimitives.pas b/CryptoLib/src/Misc/ClpBinaryPrimitives.pas
index 61c4b8c6..d501c788 100644
--- a/CryptoLib/src/Misc/ClpBinaryPrimitives.pas
+++ b/CryptoLib/src/Misc/ClpBinaryPrimitives.pas
@@ -21,9 +21,7 @@
interface
uses
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
ClpBitOperations,
-{$ENDIF}
SysUtils,
ClpCryptoLibTypes;
@@ -32,28 +30,62 @@ TBinaryPrimitives = class
private
class procedure CheckBounds(const AData: TCryptoLibByteArray; AOffset, ANeeded: Integer); static; inline;
- // UInt16 helpers
- class procedure WriteUInt16LEInternal(AValue: UInt16; const AData: TCryptoLibByteArray; AOffset: Integer); static; inline;
- class procedure WriteUInt16BEInternal(AValue: UInt16; const AData: TCryptoLibByteArray; AOffset: Integer); static; inline;
- class function ReadUInt16LEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16; static; inline;
- class function ReadUInt16BEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16; static; inline;
-
- // UInt32 helpers
- class procedure WriteUInt32LEInternal(AValue: UInt32; const AData: TCryptoLibByteArray; AOffset: Integer); static; inline;
- class procedure WriteUInt32BEInternal(AValue: UInt32; const AData: TCryptoLibByteArray; AOffset: Integer); static; inline;
- class function ReadUInt32LEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32; static; inline;
- class function ReadUInt32BEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32; static; inline;
-
- // UInt64 helpers
- class procedure WriteUInt64LEInternal(AValue: UInt64; const AData: TCryptoLibByteArray; AOffset: Integer); static; inline;
- class procedure WriteUInt64BEInternal(AValue: UInt64; const AData: TCryptoLibByteArray; AOffset: Integer); static; inline;
- class function ReadUInt64LEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64; static; inline;
- class function ReadUInt64BEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64; static; inline;
+ // Wire LE/BE value to native integer
+ class function LeToNativeUInt16(AValue: UInt16): UInt16; static; inline;
+ class function LeToNativeUInt32(AValue: UInt32): UInt32; static; inline;
+ class function LeToNativeUInt64(AValue: UInt64): UInt64; static; inline;
+ class function BeToNativeUInt16(AValue: UInt16): UInt16; static; inline;
+ class function BeToNativeUInt32(AValue: UInt32): UInt32; static; inline;
+ class function BeToNativeUInt64(AValue: UInt64): UInt64; static; inline;
+
+ // Copy with byte-reversal within each 32/64-bit lane
+ class procedure SwapCopyUInt32(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static;
+ class procedure SwapCopyUInt64(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static;
+
+ // Semantic LE/BE read/write at PByte+Offset
+ class function ReadUInt16LEAt(AInput: PByte; AOffset: Integer): UInt16; static; inline;
+ class function ReadUInt16BEAt(AInput: PByte; AOffset: Integer): UInt16; static; inline;
+ class function ReadUInt32LEAt(AInput: PByte; AOffset: Integer): UInt32; static; inline;
+ class function ReadUInt32BEAt(AInput: PByte; AOffset: Integer): UInt32; static; inline;
+ class function ReadUInt64LEAt(AInput: PByte; AOffset: Integer): UInt64; static; inline;
+ class function ReadUInt64BEAt(AInput: PByte; AOffset: Integer): UInt64; static; inline;
+
+ class procedure WriteUInt16LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16); static; inline;
+ class procedure WriteUInt16BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16); static; inline;
+ class procedure WriteUInt32LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32); static; inline;
+ class procedure WriteUInt32BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32); static; inline;
+ class procedure WriteUInt64LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64); static; inline;
+ class procedure WriteUInt64BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64); static; inline;
public
- class procedure WriteUInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt16); static; inline;
- class procedure WriteUInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt32); static; inline;
- class procedure WriteUInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt64); static; inline;
+ /// Alignment-safe native-order word load (not a wire-endian read).
+ class function LoadUInt16(AInput: PWord): UInt16; static; inline;
+ /// Alignment-safe native-order dword load (not a wire-endian read).
+ class function LoadUInt32(AInput: PCardinal): UInt32; static; inline;
+ /// Alignment-safe native-order qword load (not a wire-endian read).
+ class function LoadUInt64(AInput: PUInt64): UInt64; static; inline;
+ /// Alignment-safe native-order word store (not a wire-endian write).
+ class procedure StoreUInt16(AOutput: PWord; AValue: UInt16); static; inline;
+ /// Alignment-safe native-order dword store (not a wire-endian write).
+ class procedure StoreUInt32(AOutput: PCardinal; AValue: UInt32); static; inline;
+ /// Alignment-safe native-order qword store (not a wire-endian write).
+ class procedure StoreUInt64(AOutput: PUInt64; AValue: UInt64); static; inline;
+
+ // Copy block; preserve LE or BE wire layout
+ class procedure CopyUInt32LittleEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline;
+ class procedure CopyUInt32BigEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline;
+ class procedure CopyUInt64LittleEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline;
+ class procedure CopyUInt64BigEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline;
+
+ class procedure WriteUInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt16); overload; static; inline;
+ class procedure WriteUInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt32); overload; static; inline;
+ class procedure WriteUInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt64); overload; static; inline;
class procedure WriteInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int16); static; inline;
class procedure WriteInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int32); static; inline;
@@ -62,9 +94,9 @@ TBinaryPrimitives = class
class procedure WriteSingleLittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Single); static; inline;
class procedure WriteDoubleLittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Double); static; inline;
- class procedure WriteUInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt16); static; inline;
- class procedure WriteUInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt32); static; inline;
- class procedure WriteUInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt64); static; inline;
+ class procedure WriteUInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt16); overload; static; inline;
+ class procedure WriteUInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt32); overload; static; inline;
+ class procedure WriteUInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt64); overload; static; inline;
class procedure WriteInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int16); static; inline;
class procedure WriteInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int32); static; inline;
@@ -73,9 +105,9 @@ TBinaryPrimitives = class
class procedure WriteSingleBigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Single); static; inline;
class procedure WriteDoubleBigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Double); static; inline;
- class function ReadUInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16; static; inline;
- class function ReadUInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32; static; inline;
- class function ReadUInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64; static; inline;
+ class function ReadUInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16; overload; static; inline;
+ class function ReadUInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32; overload; static; inline;
+ class function ReadUInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64; overload; static; inline;
class function ReadInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int16; static; inline;
class function ReadInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int32; static; inline;
@@ -84,9 +116,9 @@ TBinaryPrimitives = class
class function ReadSingleLittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Single; static; inline;
class function ReadDoubleLittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Double; static; inline;
- class function ReadUInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16; static; inline;
- class function ReadUInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32; static; inline;
- class function ReadUInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64; static; inline;
+ class function ReadUInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16; overload; static; inline;
+ class function ReadUInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32; overload; static; inline;
+ class function ReadUInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64; overload; static; inline;
class function ReadInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int16; static; inline;
class function ReadInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int32; static; inline;
@@ -94,6 +126,23 @@ TBinaryPrimitives = class
class function ReadSingleBigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Single; static; inline;
class function ReadDoubleBigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Double; static; inline;
+
+ // PByte+Offset overloads
+ class procedure WriteUInt16LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16); overload; static; inline;
+ class procedure WriteUInt32LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32); overload; static; inline;
+ class procedure WriteUInt64LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64); overload; static; inline;
+
+ class procedure WriteUInt16BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16); overload; static; inline;
+ class procedure WriteUInt32BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32); overload; static; inline;
+ class procedure WriteUInt64BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64); overload; static; inline;
+
+ class function ReadUInt16LittleEndian(AInput: PByte; AOffset: Integer): UInt16; overload; static; inline;
+ class function ReadUInt32LittleEndian(AInput: PByte; AOffset: Integer): UInt32; overload; static; inline;
+ class function ReadUInt64LittleEndian(AInput: PByte; AOffset: Integer): UInt64; overload; static; inline;
+
+ class function ReadUInt16BigEndian(AInput: PByte; AOffset: Integer): UInt16; overload; static; inline;
+ class function ReadUInt32BigEndian(AInput: PByte; AOffset: Integer): UInt32; overload; static; inline;
+ class function ReadUInt64BigEndian(AInput: PByte; AOffset: Integer): UInt64; overload; static; inline;
end;
implementation
@@ -107,205 +156,447 @@ class procedure TBinaryPrimitives.CheckBounds(const AData: TCryptoLibByteArray;
end;
// ============================================================================
-// UInt16 Internal Helpers
+// Host-endian conversion
// ============================================================================
-class procedure TBinaryPrimitives.WriteUInt16LEInternal(AValue: UInt16; const AData: TCryptoLibByteArray; AOffset: Integer);
+class function TBinaryPrimitives.LeToNativeUInt16(AValue: UInt16): UInt16;
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Result := AValue;
+{$ELSE}
+ Result := TBitOperations.ReverseBytesUInt16(AValue);
+{$ENDIF}
+end;
+
+class function TBinaryPrimitives.LeToNativeUInt32(AValue: UInt32): UInt32;
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Result := AValue;
+{$ELSE}
+ Result := TBitOperations.ReverseBytesUInt32(AValue);
+{$ENDIF}
+end;
+
+class function TBinaryPrimitives.LeToNativeUInt64(AValue: UInt64): UInt64;
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- PWord(@AData[AOffset])^ := AValue;
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Result := AValue;
{$ELSE}
- AData[AOffset] := Byte(AValue);
- AData[AOffset + 1] := Byte(AValue shr 8);
+ Result := TBitOperations.ReverseBytesUInt64(AValue);
{$ENDIF}
end;
-class procedure TBinaryPrimitives.WriteUInt16BEInternal(AValue: UInt16; const AData: TCryptoLibByteArray; AOffset: Integer);
+class function TBinaryPrimitives.BeToNativeUInt16(AValue: UInt16): UInt16;
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- PWord(@AData[AOffset])^ := TBitOperations.ReverseBytesUInt16(AValue);
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Result := TBitOperations.ReverseBytesUInt16(AValue);
{$ELSE}
- AData[AOffset] := Byte(AValue shr 8);
- AData[AOffset + 1] := Byte(AValue);
+ Result := AValue;
{$ENDIF}
end;
-class function TBinaryPrimitives.ReadUInt16LEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16;
+class function TBinaryPrimitives.BeToNativeUInt32(AValue: UInt32): UInt32;
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- Result := PWord(@AData[AOffset])^;
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Result := TBitOperations.ReverseBytesUInt32(AValue);
{$ELSE}
- Result := UInt16(AData[AOffset]) or (UInt16(AData[AOffset + 1]) shl 8);
+ Result := AValue;
{$ENDIF}
end;
-class function TBinaryPrimitives.ReadUInt16BEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16;
+class function TBinaryPrimitives.BeToNativeUInt64(AValue: UInt64): UInt64;
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- Result := TBitOperations.ReverseBytesUInt16(PWord(@AData[AOffset])^);
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Result := TBitOperations.ReverseBytesUInt64(AValue);
{$ELSE}
- Result := (UInt16(AData[AOffset]) shl 8) or UInt16(AData[AOffset + 1]);
+ Result := AValue;
{$ENDIF}
end;
// ============================================================================
-// UInt32 Internal Helpers
+// Raw memory load/store
// ============================================================================
-class procedure TBinaryPrimitives.WriteUInt32LEInternal(AValue: UInt32; const AData: TCryptoLibByteArray; AOffset: Integer);
+class function TBinaryPrimitives.LoadUInt16(AInput: PWord): UInt16;
+begin
+{$IFDEF CRYPTOLIB_REQUIRES_PROPER_ALIGNMENT}
+ Move(AInput^, Result, SizeOf(UInt16));
+{$ELSE}
+ Result := AInput^;
+{$ENDIF}
+end;
+
+class function TBinaryPrimitives.LoadUInt32(AInput: PCardinal): UInt32;
+begin
+{$IFDEF CRYPTOLIB_REQUIRES_PROPER_ALIGNMENT}
+ Move(AInput^, Result, SizeOf(UInt32));
+{$ELSE}
+ Result := AInput^;
+{$ENDIF}
+end;
+
+class function TBinaryPrimitives.LoadUInt64(AInput: PUInt64): UInt64;
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- PUInt32(@AData[AOffset])^ := AValue;
+{$IFDEF CRYPTOLIB_REQUIRES_PROPER_ALIGNMENT}
+ Move(AInput^, Result, SizeOf(UInt64));
{$ELSE}
- AData[AOffset] := Byte(AValue);
- AData[AOffset + 1] := Byte(AValue shr 8);
- AData[AOffset + 2] := Byte(AValue shr 16);
- AData[AOffset + 3] := Byte(AValue shr 24);
+ Result := AInput^;
{$ENDIF}
end;
-class procedure TBinaryPrimitives.WriteUInt32BEInternal(AValue: UInt32; const AData: TCryptoLibByteArray; AOffset: Integer);
+class procedure TBinaryPrimitives.StoreUInt16(AOutput: PWord; AValue: UInt16);
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- PUInt32(@AData[AOffset])^ := TBitOperations.ReverseBytesUInt32(AValue);
+{$IFDEF CRYPTOLIB_REQUIRES_PROPER_ALIGNMENT}
+ Move(AValue, AOutput^, SizeOf(UInt16));
{$ELSE}
- AData[AOffset] := Byte(AValue shr 24);
- AData[AOffset + 1] := Byte(AValue shr 16);
- AData[AOffset + 2] := Byte(AValue shr 8);
- AData[AOffset + 3] := Byte(AValue);
+ AOutput^ := AValue;
{$ENDIF}
end;
-class function TBinaryPrimitives.ReadUInt32LEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32;
+class procedure TBinaryPrimitives.StoreUInt32(AOutput: PCardinal; AValue: UInt32);
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- Result := PUInt32(@AData[AOffset])^;
+{$IFDEF CRYPTOLIB_REQUIRES_PROPER_ALIGNMENT}
+ Move(AValue, AOutput^, SizeOf(UInt32));
{$ELSE}
- Result := UInt32(AData[AOffset]) or
- (UInt32(AData[AOffset + 1]) shl 8) or
- (UInt32(AData[AOffset + 2]) shl 16) or
- (UInt32(AData[AOffset + 3]) shl 24);
+ AOutput^ := AValue;
{$ENDIF}
end;
-class function TBinaryPrimitives.ReadUInt32BEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32;
+class procedure TBinaryPrimitives.StoreUInt64(AOutput: PUInt64; AValue: UInt64);
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- Result := TBitOperations.ReverseBytesUInt32(PUInt32(@AData[AOffset])^);
+{$IFDEF CRYPTOLIB_REQUIRES_PROPER_ALIGNMENT}
+ Move(AValue, AOutput^, SizeOf(UInt64));
{$ELSE}
- Result := (UInt32(AData[AOffset]) shl 24) or
- (UInt32(AData[AOffset + 1]) shl 16) or
- (UInt32(AData[AOffset + 2]) shl 8) or
- UInt32(AData[AOffset + 3]);
+ AOutput^ := AValue;
{$ENDIF}
end;
// ============================================================================
-// UInt64 Internal Helpers
+// Bulk copy
// ============================================================================
-class procedure TBinaryPrimitives.WriteUInt64LEInternal(AValue: UInt64; const AData: TCryptoLibByteArray; AOffset: Integer);
+class procedure TBinaryPrimitives.SwapCopyUInt32(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer);
+var
+ LSrcWord, LDestWord, LSrcWordEnd: PCardinal;
+ LSrcByte, LDestByte: PByte;
+ LByteIdx: Integer;
+begin
+ if ((NativeUInt(PByte(ADestination)) or NativeUInt(PByte(ASource)) or
+ NativeUInt(ASourceIndex) or NativeUInt(ADestinationIndex) or NativeUInt(ASize)) and 3) = 0 then
+ begin
+ LSrcWord := PCardinal(PByte(ASource) + ASourceIndex);
+ LSrcWordEnd := PCardinal(PByte(ASource) + ASourceIndex + ASize);
+ LDestWord := PCardinal(PByte(ADestination) + ADestinationIndex);
+ while LSrcWord < LSrcWordEnd do
+ begin
+ LDestWord^ := TBitOperations.ReverseBytesUInt32(LSrcWord^);
+ Inc(LDestWord);
+ Inc(LSrcWord);
+ end;
+ end
+ else
+ begin
+ LSrcByte := PByte(ASource) + ASourceIndex;
+ LDestByte := PByte(ADestination) + ADestinationIndex;
+ LByteIdx := 0;
+ while LByteIdx < ASize do
+ begin
+ LDestByte[LByteIdx] := LSrcByte[LByteIdx xor 3];
+ Inc(LByteIdx);
+ end;
+ end;
+end;
+
+class procedure TBinaryPrimitives.SwapCopyUInt64(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer);
+var
+ LSrcWord, LDestWord, LSrcWordEnd: PUInt64;
+ LSrcByte, LDestByte: PByte;
+ LByteIdx: Integer;
+begin
+ if ((NativeUInt(PByte(ADestination)) or NativeUInt(PByte(ASource)) or
+ NativeUInt(ASourceIndex) or NativeUInt(ADestinationIndex) or NativeUInt(ASize)) and 7) = 0 then
+ begin
+ LSrcWord := PUInt64(PByte(ASource) + ASourceIndex);
+ LSrcWordEnd := PUInt64(PByte(ASource) + ASourceIndex + ASize);
+ LDestWord := PUInt64(PByte(ADestination) + ADestinationIndex);
+ while LSrcWord < LSrcWordEnd do
+ begin
+ LDestWord^ := TBitOperations.ReverseBytesUInt64(LSrcWord^);
+ Inc(LDestWord);
+ Inc(LSrcWord);
+ end;
+ end
+ else
+ begin
+ LSrcByte := PByte(ASource) + ASourceIndex;
+ LDestByte := PByte(ADestination) + ADestinationIndex;
+ LByteIdx := 0;
+ while LByteIdx < ASize do
+ begin
+ LDestByte[LByteIdx] := LSrcByte[LByteIdx xor 7];
+ Inc(LByteIdx);
+ end;
+ end;
+end;
+
+class procedure TBinaryPrimitives.CopyUInt32LittleEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer);
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Move(Pointer(PByte(ASource) + ASourceIndex)^,
+ Pointer(PByte(ADestination) + ADestinationIndex)^, ASize);
+{$ELSE}
+ SwapCopyUInt32(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize);
+{$ENDIF}
+end;
+
+class procedure TBinaryPrimitives.CopyUInt32BigEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer);
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ SwapCopyUInt32(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize);
+{$ELSE}
+ Move(Pointer(PByte(ASource) + ASourceIndex)^,
+ Pointer(PByte(ADestination) + ADestinationIndex)^, ASize);
+{$ENDIF}
+end;
+
+class procedure TBinaryPrimitives.CopyUInt64LittleEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer);
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ Move(Pointer(PByte(ASource) + ASourceIndex)^,
+ Pointer(PByte(ADestination) + ADestinationIndex)^, ASize);
+{$ELSE}
+ SwapCopyUInt64(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize);
+{$ENDIF}
+end;
+
+class procedure TBinaryPrimitives.CopyUInt64BigEndian(ASource: Pointer; ASourceIndex: Integer;
+ ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer);
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ SwapCopyUInt64(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize);
+{$ELSE}
+ Move(Pointer(PByte(ASource) + ASourceIndex)^,
+ Pointer(PByte(ADestination) + ADestinationIndex)^, ASize);
+{$ENDIF}
+end;
+
+// ============================================================================
+// Pointer read/write cores
+// ============================================================================
+
+class function TBinaryPrimitives.ReadUInt16LEAt(AInput: PByte; AOffset: Integer): UInt16;
+begin
+ Result := LeToNativeUInt16(LoadUInt16(PWord(AInput + AOffset)));
+end;
+
+class function TBinaryPrimitives.ReadUInt16BEAt(AInput: PByte; AOffset: Integer): UInt16;
+begin
+ Result := BeToNativeUInt16(LoadUInt16(PWord(AInput + AOffset)));
+end;
+
+class function TBinaryPrimitives.ReadUInt32LEAt(AInput: PByte; AOffset: Integer): UInt32;
+begin
+ Result := LeToNativeUInt32(LoadUInt32(PCardinal(AInput + AOffset)));
+end;
+
+class function TBinaryPrimitives.ReadUInt32BEAt(AInput: PByte; AOffset: Integer): UInt32;
+begin
+ Result := BeToNativeUInt32(LoadUInt32(PCardinal(AInput + AOffset)));
+end;
+
+class function TBinaryPrimitives.ReadUInt64LEAt(AInput: PByte; AOffset: Integer): UInt64;
+begin
+ Result := LeToNativeUInt64(LoadUInt64(PUInt64(AInput + AOffset)));
+end;
+
+class function TBinaryPrimitives.ReadUInt64BEAt(AInput: PByte; AOffset: Integer): UInt64;
+begin
+ Result := BeToNativeUInt64(LoadUInt64(PUInt64(AInput + AOffset)));
+end;
+
+class procedure TBinaryPrimitives.WriteUInt16LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16);
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ StoreUInt16(PWord(AOutput + AOffset), AValue);
+{$ELSE}
+ AOutput[AOffset] := Byte(AValue);
+ AOutput[AOffset + 1] := Byte(AValue shr 8);
+{$ENDIF}
+end;
+
+class procedure TBinaryPrimitives.WriteUInt16BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16);
+begin
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ AOutput[AOffset] := Byte(AValue shr 8);
+ AOutput[AOffset + 1] := Byte(AValue);
+{$ELSE}
+ StoreUInt16(PWord(AOutput + AOffset), AValue);
+{$ENDIF}
+end;
+
+class procedure TBinaryPrimitives.WriteUInt32LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32);
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- PUInt64(@AData[AOffset])^ := AValue;
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ StoreUInt32(PCardinal(AOutput + AOffset), AValue);
{$ELSE}
- AData[AOffset] := Byte(AValue);
- AData[AOffset + 1] := Byte(AValue shr 8);
- AData[AOffset + 2] := Byte(AValue shr 16);
- AData[AOffset + 3] := Byte(AValue shr 24);
- AData[AOffset + 4] := Byte(AValue shr 32);
- AData[AOffset + 5] := Byte(AValue shr 40);
- AData[AOffset + 6] := Byte(AValue shr 48);
- AData[AOffset + 7] := Byte(AValue shr 56);
+ AOutput[AOffset] := Byte(AValue);
+ AOutput[AOffset + 1] := Byte(AValue shr 8);
+ AOutput[AOffset + 2] := Byte(AValue shr 16);
+ AOutput[AOffset + 3] := Byte(AValue shr 24);
{$ENDIF}
end;
-class procedure TBinaryPrimitives.WriteUInt64BEInternal(AValue: UInt64; const AData: TCryptoLibByteArray; AOffset: Integer);
+class procedure TBinaryPrimitives.WriteUInt32BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32);
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- PUInt64(@AData[AOffset])^ := TBitOperations.ReverseBytesUInt64(AValue);
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ AOutput[AOffset] := Byte(AValue shr 24);
+ AOutput[AOffset + 1] := Byte(AValue shr 16);
+ AOutput[AOffset + 2] := Byte(AValue shr 8);
+ AOutput[AOffset + 3] := Byte(AValue);
{$ELSE}
- AData[AOffset] := Byte(AValue shr 56);
- AData[AOffset + 1] := Byte(AValue shr 48);
- AData[AOffset + 2] := Byte(AValue shr 40);
- AData[AOffset + 3] := Byte(AValue shr 32);
- AData[AOffset + 4] := Byte(AValue shr 24);
- AData[AOffset + 5] := Byte(AValue shr 16);
- AData[AOffset + 6] := Byte(AValue shr 8);
- AData[AOffset + 7] := Byte(AValue);
+ StoreUInt32(PCardinal(AOutput + AOffset), AValue);
{$ENDIF}
end;
-class function TBinaryPrimitives.ReadUInt64LEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64;
+class procedure TBinaryPrimitives.WriteUInt64LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64);
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- Result := PUInt64(@AData[AOffset])^;
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ StoreUInt64(PUInt64(AOutput + AOffset), AValue);
{$ELSE}
- Result := UInt64(AData[AOffset]) or
- (UInt64(AData[AOffset + 1]) shl 8) or
- (UInt64(AData[AOffset + 2]) shl 16) or
- (UInt64(AData[AOffset + 3]) shl 24) or
- (UInt64(AData[AOffset + 4]) shl 32) or
- (UInt64(AData[AOffset + 5]) shl 40) or
- (UInt64(AData[AOffset + 6]) shl 48) or
- (UInt64(AData[AOffset + 7]) shl 56);
+ AOutput[AOffset] := Byte(AValue);
+ AOutput[AOffset + 1] := Byte(AValue shr 8);
+ AOutput[AOffset + 2] := Byte(AValue shr 16);
+ AOutput[AOffset + 3] := Byte(AValue shr 24);
+ AOutput[AOffset + 4] := Byte(AValue shr 32);
+ AOutput[AOffset + 5] := Byte(AValue shr 40);
+ AOutput[AOffset + 6] := Byte(AValue shr 48);
+ AOutput[AOffset + 7] := Byte(AValue shr 56);
{$ENDIF}
end;
-class function TBinaryPrimitives.ReadUInt64BEInternal(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64;
+class procedure TBinaryPrimitives.WriteUInt64BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64);
begin
-{$IFDEF CRYPTOLIB_HAS_FAST_UNALIGNED_ACCESS_LE}
- Result := TBitOperations.ReverseBytesUInt64(PUInt64(@AData[AOffset])^);
+{$IFDEF CRYPTOLIB_LITTLE_ENDIAN}
+ AOutput[AOffset] := Byte(AValue shr 56);
+ AOutput[AOffset + 1] := Byte(AValue shr 48);
+ AOutput[AOffset + 2] := Byte(AValue shr 40);
+ AOutput[AOffset + 3] := Byte(AValue shr 32);
+ AOutput[AOffset + 4] := Byte(AValue shr 24);
+ AOutput[AOffset + 5] := Byte(AValue shr 16);
+ AOutput[AOffset + 6] := Byte(AValue shr 8);
+ AOutput[AOffset + 7] := Byte(AValue);
{$ELSE}
- Result := (UInt64(AData[AOffset]) shl 56) or
- (UInt64(AData[AOffset + 1]) shl 48) or
- (UInt64(AData[AOffset + 2]) shl 40) or
- (UInt64(AData[AOffset + 3]) shl 32) or
- (UInt64(AData[AOffset + 4]) shl 24) or
- (UInt64(AData[AOffset + 5]) shl 16) or
- (UInt64(AData[AOffset + 6]) shl 8) or
- UInt64(AData[AOffset + 7]);
+ StoreUInt64(PUInt64(AOutput + AOffset), AValue);
{$ENDIF}
end;
// ============================================================================
-// Public Write Methods - Little Endian
+// Public pointer read/write overloads
+// ============================================================================
+
+class procedure TBinaryPrimitives.WriteUInt16LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16);
+begin
+ WriteUInt16LEAt(AOutput, AOffset, AValue);
+end;
+
+class procedure TBinaryPrimitives.WriteUInt32LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32);
+begin
+ WriteUInt32LEAt(AOutput, AOffset, AValue);
+end;
+
+class procedure TBinaryPrimitives.WriteUInt64LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64);
+begin
+ WriteUInt64LEAt(AOutput, AOffset, AValue);
+end;
+
+class procedure TBinaryPrimitives.WriteUInt16BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16);
+begin
+ WriteUInt16BEAt(AOutput, AOffset, AValue);
+end;
+
+class procedure TBinaryPrimitives.WriteUInt32BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32);
+begin
+ WriteUInt32BEAt(AOutput, AOffset, AValue);
+end;
+
+class procedure TBinaryPrimitives.WriteUInt64BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64);
+begin
+ WriteUInt64BEAt(AOutput, AOffset, AValue);
+end;
+
+class function TBinaryPrimitives.ReadUInt16LittleEndian(AInput: PByte; AOffset: Integer): UInt16;
+begin
+ Result := ReadUInt16LEAt(AInput, AOffset);
+end;
+
+class function TBinaryPrimitives.ReadUInt32LittleEndian(AInput: PByte; AOffset: Integer): UInt32;
+begin
+ Result := ReadUInt32LEAt(AInput, AOffset);
+end;
+
+class function TBinaryPrimitives.ReadUInt64LittleEndian(AInput: PByte; AOffset: Integer): UInt64;
+begin
+ Result := ReadUInt64LEAt(AInput, AOffset);
+end;
+
+class function TBinaryPrimitives.ReadUInt16BigEndian(AInput: PByte; AOffset: Integer): UInt16;
+begin
+ Result := ReadUInt16BEAt(AInput, AOffset);
+end;
+
+class function TBinaryPrimitives.ReadUInt32BigEndian(AInput: PByte; AOffset: Integer): UInt32;
+begin
+ Result := ReadUInt32BEAt(AInput, AOffset);
+end;
+
+class function TBinaryPrimitives.ReadUInt64BigEndian(AInput: PByte; AOffset: Integer): UInt64;
+begin
+ Result := ReadUInt64BEAt(AInput, AOffset);
+end;
+
+// ============================================================================
+// Public Write Methods - Little Endian (TArray)
// ============================================================================
class procedure TBinaryPrimitives.WriteUInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt16);
begin
CheckBounds(AData, AOffset, SizeOf(UInt16));
- WriteUInt16LEInternal(AValue, AData, AOffset);
+ WriteUInt16LEAt(PByte(AData), AOffset, AValue);
end;
class procedure TBinaryPrimitives.WriteUInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt32);
begin
CheckBounds(AData, AOffset, SizeOf(UInt32));
- WriteUInt32LEInternal(AValue, AData, AOffset);
+ WriteUInt32LEAt(PByte(AData), AOffset, AValue);
end;
class procedure TBinaryPrimitives.WriteUInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt64);
begin
CheckBounds(AData, AOffset, SizeOf(UInt64));
- WriteUInt64LEInternal(AValue, AData, AOffset);
+ WriteUInt64LEAt(PByte(AData), AOffset, AValue);
end;
class procedure TBinaryPrimitives.WriteInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int16);
begin
CheckBounds(AData, AOffset, SizeOf(Int16));
- WriteUInt16LEInternal(UInt16(AValue), AData, AOffset);
+ WriteUInt16LEAt(PByte(AData), AOffset, UInt16(AValue));
end;
class procedure TBinaryPrimitives.WriteInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int32);
begin
CheckBounds(AData, AOffset, SizeOf(Int32));
- WriteUInt32LEInternal(UInt32(AValue), AData, AOffset);
+ WriteUInt32LEAt(PByte(AData), AOffset, UInt32(AValue));
end;
class procedure TBinaryPrimitives.WriteInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int64);
begin
CheckBounds(AData, AOffset, SizeOf(Int64));
- WriteUInt64LEInternal(UInt64(AValue), AData, AOffset);
+ WriteUInt64LEAt(PByte(AData), AOffset, UInt64(AValue));
end;
class procedure TBinaryPrimitives.WriteSingleLittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Single);
@@ -314,7 +605,7 @@ class procedure TBinaryPrimitives.WriteSingleLittleEndian(const AData: TCryptoLi
begin
CheckBounds(AData, AOffset, SizeOf(Single));
Move(AValue, LBits, SizeOf(Single));
- WriteUInt32LEInternal(LBits, AData, AOffset);
+ WriteUInt32LEAt(PByte(AData), AOffset, LBits);
end;
class procedure TBinaryPrimitives.WriteDoubleLittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Double);
@@ -323,47 +614,47 @@ class procedure TBinaryPrimitives.WriteDoubleLittleEndian(const AData: TCryptoLi
begin
CheckBounds(AData, AOffset, SizeOf(Double));
Move(AValue, LBits, SizeOf(Double));
- WriteUInt64LEInternal(LBits, AData, AOffset);
+ WriteUInt64LEAt(PByte(AData), AOffset, LBits);
end;
// ============================================================================
-// Public Write Methods - Big Endian
+// Public Write Methods - Big Endian (TArray)
// ============================================================================
class procedure TBinaryPrimitives.WriteUInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt16);
begin
CheckBounds(AData, AOffset, SizeOf(UInt16));
- WriteUInt16BEInternal(AValue, AData, AOffset);
+ WriteUInt16BEAt(PByte(AData), AOffset, AValue);
end;
class procedure TBinaryPrimitives.WriteUInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt32);
begin
CheckBounds(AData, AOffset, SizeOf(UInt32));
- WriteUInt32BEInternal(AValue, AData, AOffset);
+ WriteUInt32BEAt(PByte(AData), AOffset, AValue);
end;
class procedure TBinaryPrimitives.WriteUInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: UInt64);
begin
CheckBounds(AData, AOffset, SizeOf(UInt64));
- WriteUInt64BEInternal(AValue, AData, AOffset);
+ WriteUInt64BEAt(PByte(AData), AOffset, AValue);
end;
class procedure TBinaryPrimitives.WriteInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int16);
begin
CheckBounds(AData, AOffset, SizeOf(Int16));
- WriteUInt16BEInternal(UInt16(AValue), AData, AOffset);
+ WriteUInt16BEAt(PByte(AData), AOffset, UInt16(AValue));
end;
class procedure TBinaryPrimitives.WriteInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int32);
begin
CheckBounds(AData, AOffset, SizeOf(Int32));
- WriteUInt32BEInternal(UInt32(AValue), AData, AOffset);
+ WriteUInt32BEAt(PByte(AData), AOffset, UInt32(AValue));
end;
class procedure TBinaryPrimitives.WriteInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Int64);
begin
CheckBounds(AData, AOffset, SizeOf(Int64));
- WriteUInt64BEInternal(UInt64(AValue), AData, AOffset);
+ WriteUInt64BEAt(PByte(AData), AOffset, UInt64(AValue));
end;
class procedure TBinaryPrimitives.WriteSingleBigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Single);
@@ -372,7 +663,7 @@ class procedure TBinaryPrimitives.WriteSingleBigEndian(const AData: TCryptoLibBy
begin
CheckBounds(AData, AOffset, SizeOf(Single));
Move(AValue, LBits, SizeOf(Single));
- WriteUInt32BEInternal(LBits, AData, AOffset);
+ WriteUInt32BEAt(PByte(AData), AOffset, LBits);
end;
class procedure TBinaryPrimitives.WriteDoubleBigEndian(const AData: TCryptoLibByteArray; AOffset: Integer; AValue: Double);
@@ -381,47 +672,47 @@ class procedure TBinaryPrimitives.WriteDoubleBigEndian(const AData: TCryptoLibBy
begin
CheckBounds(AData, AOffset, SizeOf(Double));
Move(AValue, LBits, SizeOf(Double));
- WriteUInt64BEInternal(LBits, AData, AOffset);
+ WriteUInt64BEAt(PByte(AData), AOffset, LBits);
end;
// ============================================================================
-// Public Read Methods - Little Endian
+// Public Read Methods - Little Endian (TArray)
// ============================================================================
class function TBinaryPrimitives.ReadUInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16;
begin
CheckBounds(AData, AOffset, SizeOf(UInt16));
- Result := ReadUInt16LEInternal(AData, AOffset);
+ Result := ReadUInt16LEAt(PByte(AData), AOffset);
end;
class function TBinaryPrimitives.ReadUInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32;
begin
CheckBounds(AData, AOffset, SizeOf(UInt32));
- Result := ReadUInt32LEInternal(AData, AOffset);
+ Result := ReadUInt32LEAt(PByte(AData), AOffset);
end;
class function TBinaryPrimitives.ReadUInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64;
begin
CheckBounds(AData, AOffset, SizeOf(UInt64));
- Result := ReadUInt64LEInternal(AData, AOffset);
+ Result := ReadUInt64LEAt(PByte(AData), AOffset);
end;
class function TBinaryPrimitives.ReadInt16LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int16;
begin
CheckBounds(AData, AOffset, SizeOf(Int16));
- Result := Int16(ReadUInt16LEInternal(AData, AOffset));
+ Result := Int16(ReadUInt16LEAt(PByte(AData), AOffset));
end;
class function TBinaryPrimitives.ReadInt32LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int32;
begin
CheckBounds(AData, AOffset, SizeOf(Int32));
- Result := Int32(ReadUInt32LEInternal(AData, AOffset));
+ Result := Int32(ReadUInt32LEAt(PByte(AData), AOffset));
end;
class function TBinaryPrimitives.ReadInt64LittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int64;
begin
CheckBounds(AData, AOffset, SizeOf(Int64));
- Result := Int64(ReadUInt64LEInternal(AData, AOffset));
+ Result := Int64(ReadUInt64LEAt(PByte(AData), AOffset));
end;
class function TBinaryPrimitives.ReadSingleLittleEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Single;
@@ -429,7 +720,7 @@ class function TBinaryPrimitives.ReadSingleLittleEndian(const AData: TCryptoLibB
LBits: UInt32;
begin
CheckBounds(AData, AOffset, SizeOf(Single));
- LBits := ReadUInt32LEInternal(AData, AOffset);
+ LBits := ReadUInt32LEAt(PByte(AData), AOffset);
Move(LBits, Result, SizeOf(Single));
end;
@@ -438,48 +729,48 @@ class function TBinaryPrimitives.ReadDoubleLittleEndian(const AData: TCryptoLibB
LBits: UInt64;
begin
CheckBounds(AData, AOffset, SizeOf(Double));
- LBits := ReadUInt64LEInternal(AData, AOffset);
+ LBits := ReadUInt64LEAt(PByte(AData), AOffset);
Move(LBits, Result, SizeOf(Double));
end;
// ============================================================================
-// Public Read Methods - Big Endian
+// Public Read Methods - Big Endian (TArray)
// ============================================================================
class function TBinaryPrimitives.ReadUInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt16;
begin
CheckBounds(AData, AOffset, SizeOf(UInt16));
- Result := ReadUInt16BEInternal(AData, AOffset);
+ Result := ReadUInt16BEAt(PByte(AData), AOffset);
end;
class function TBinaryPrimitives.ReadUInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt32;
begin
CheckBounds(AData, AOffset, SizeOf(UInt32));
- Result := ReadUInt32BEInternal(AData, AOffset);
+ Result := ReadUInt32BEAt(PByte(AData), AOffset);
end;
class function TBinaryPrimitives.ReadUInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): UInt64;
begin
CheckBounds(AData, AOffset, SizeOf(UInt64));
- Result := ReadUInt64BEInternal(AData, AOffset);
+ Result := ReadUInt64BEAt(PByte(AData), AOffset);
end;
class function TBinaryPrimitives.ReadInt16BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int16;
begin
CheckBounds(AData, AOffset, SizeOf(Int16));
- Result := Int16(ReadUInt16BEInternal(AData, AOffset));
+ Result := Int16(ReadUInt16BEAt(PByte(AData), AOffset));
end;
class function TBinaryPrimitives.ReadInt32BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int32;
begin
CheckBounds(AData, AOffset, SizeOf(Int32));
- Result := Int32(ReadUInt32BEInternal(AData, AOffset));
+ Result := Int32(ReadUInt32BEAt(PByte(AData), AOffset));
end;
class function TBinaryPrimitives.ReadInt64BigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Int64;
begin
CheckBounds(AData, AOffset, SizeOf(Int64));
- Result := Int64(ReadUInt64BEInternal(AData, AOffset));
+ Result := Int64(ReadUInt64BEAt(PByte(AData), AOffset));
end;
class function TBinaryPrimitives.ReadSingleBigEndian(const AData: TCryptoLibByteArray; AOffset: Integer): Single;
@@ -487,7 +778,7 @@ class function TBinaryPrimitives.ReadSingleBigEndian(const AData: TCryptoLibByte
LBits: UInt32;
begin
CheckBounds(AData, AOffset, SizeOf(Single));
- LBits := ReadUInt32BEInternal(AData, AOffset);
+ LBits := ReadUInt32BEAt(PByte(AData), AOffset);
Move(LBits, Result, SizeOf(Single));
end;
@@ -496,9 +787,8 @@ class function TBinaryPrimitives.ReadDoubleBigEndian(const AData: TCryptoLibByte
LBits: UInt64;
begin
CheckBounds(AData, AOffset, SizeOf(Double));
- LBits := ReadUInt64BEInternal(AData, AOffset);
+ LBits := ReadUInt64BEAt(PByte(AData), AOffset);
Move(LBits, Result, SizeOf(Double));
end;
end.
-
diff --git a/CryptoLib/src/Misc/ClpBitOperations.pas b/CryptoLib/src/Misc/ClpBitOperations.pas
index 7078fbda..94dfa436 100644
--- a/CryptoLib/src/Misc/ClpBitOperations.pas
+++ b/CryptoLib/src/Misc/ClpBitOperations.pas
@@ -21,123 +21,190 @@
interface
type
+ ///
+ /// Portable bit operations code.
+ ///
TBitOperations = class sealed(TObject)
-
public
-
+ ///
+ /// Reverses byte order of a 32-bit signed value (endian swap).
+ ///
class function ReverseBytesInt32(AValue: Int32): Int32; static; inline;
+
+ ///
+ /// Reverses bit order within a byte (MSB becomes LSB).
+ /// Does not swap or reorder bytes.
+ ///
class function ReverseBitsUInt8(AValue: UInt8): UInt8; static; inline;
+
+ ///
+ /// Reverses byte order of a 16-bit value (endian swap).
+ ///
class function ReverseBytesUInt16(AValue: UInt16): UInt16; static; inline;
+
+ ///
+ /// Reverses byte order of a 32-bit unsigned value (endian swap).
+ ///
class function ReverseBytesUInt32(AValue: UInt32): UInt32; static; inline;
+
+ ///
+ /// Reverses byte order of a 64-bit unsigned value (endian swap).
+ ///
class function ReverseBytesUInt64(AValue: UInt64): UInt64; static; inline;
///
- /// Calculates Arithmetic shift right.
+ /// Arithmetic right shift of a signed 32-bit value.
+ /// Vacated high bits replicate the sign bit.
///
- /// Int32 value to compute 'Asr' on.
- /// Byte, number of bits to shift value to.
- /// Shifted value.
+ ///
+ /// Shift count; masked to 31.
+ ///
///
- /// Emulated Implementation was gotten from FreePascal sources
+ /// Delphi uses an emulated Sar; FPC uses SarLongInt.
///
-
class function Asr32(AValue: Int32; AShiftBits: Byte): Int32; static; inline;
///
- /// Calculates Arithmetic shift right.
+ /// Arithmetic right shift of a signed 64-bit value.
+ /// Vacated high bits replicate the sign bit.
///
- /// Int64 value to compute 'Asr' on.
- /// Byte, number of bits to shift value to.
- /// Shifted value.
+ ///
+ /// Shift count; masked to 63.
+ ///
///
- /// Emulated Implementation was gotten from FreePascal sources
+ /// Delphi uses an emulated Sar; FPC uses SarInt64.
///
-
class function Asr64(AValue: Int64; AShiftBits: Byte): Int64; static; inline;
///
- /// Calculates Negative Left Shift. This was implemented to circumvent a
- /// bug in FPC ARM when performing Shift Left on certain values with a
- /// Negative Shift Bits. For example UInt32(1948415963) shl Int32(-2)
- /// should give "3221225472" but in FPC ARM, It gives "0". In some C
- /// Compilers, this is "Undefined"
+ /// Logical left shift by (32 + AShiftBits).
+ /// With negative AShiftBits, combines cross-limb carry when shifting multi-word integers.
///
- ///
- /// Value to Perform Shift On
- ///
///
- /// Integer, number of bits to shift value to. This Number Must be
- /// Negative
+ /// Must be negative; callers pass -n for a positive shift distance n.
///
- ///
- /// Shifted value.
- ///
-
+ ///
+ /// Raw shl/shr with a negative count is undefined in C/C++ and FPC.
+ /// For S in (-32, 0) this matches x86 masked shift distance (S and 31).
+ ///
class function NegativeLeftShift32(AValue: UInt32; AShiftBits: Int32): UInt32; static; inline;
///
- /// Calculates Negative Left Shift for 64-bit (same semantics as NegativeLeftShift32).
+ /// 64-bit counterpart of NegativeLeftShift32.
+ /// Effective shift distance is (64 + AShiftBits).
///
class function NegativeLeftShift64(AValue: UInt64; AShiftBits: Int32): UInt64; static; inline;
///
- /// Calculates Negative Right Shift. This was implemented to circumvent a
- /// compiler issue when performing Shift Right on certain values with a
- /// Negative Shift Bits. In some C Compilers, this is "Undefined"
+ /// Logical right shift by (32 + AShiftBits).
+ /// With negative AShiftBits, extracts upper spill bits when a limb is shifted right by n.
///
- ///
- /// Value to Perform Shift On
- ///
///
- /// Integer, number of bits to shift value to. This Number Must be
- /// Negative
+ /// Must be negative; callers pass -n for a positive shift distance n.
///
- ///
- /// Shifted value.
- ///
-
+ ///
+ /// Raw shl/shr with a negative count is undefined in C/C++ and FPC.
+ /// For S in (-32, 0) this matches x86 masked shift distance (S and 31).
+ ///
class function NegativeRightShift32(AValue: UInt32; AShiftBits: Int32): UInt32; static; inline;
///
- /// Calculates Negative Right Shift. This was implemented to circumvent a
- /// compiler issue when performing Shift Right on certain values with a
- /// Negative Shift Bits. In some C Compilers, this is "Undefined"
+ /// 64-bit counterpart of NegativeRightShift32.
+ /// Effective shift distance is (64 + AShiftBits).
///
- ///
- /// Value to Perform Shift On
- ///
- ///
- /// Integer, number of bits to shift value to. This Number Must be
- /// Negative
- ///
- ///
- /// Shifted value.
- ///
-
class function NegativeRightShift64(AValue: UInt64; AShiftBits: Int32): UInt64; static; inline;
+ ///
+ /// Rotates an 8-bit value left by AN positions.
+ /// Bits shifted out re-enter at the low-order end.
+ ///
class function RotateLeft8(AValue: Byte; AN: Int32): Byte; static; inline;
+
+ ///
+ /// Rotates a 16-bit value left by AN positions.
+ /// Bits shifted out re-enter at the low-order end.
+ ///
class function RotateLeft16(AValue: UInt16; AN: Int32): UInt16; static; inline;
+
+ ///
+ /// Rotates a 32-bit value left by AN positions.
+ /// Bits shifted out re-enter at the low-order end.
+ ///
+ ///
+ /// Non-negative rotation distance.
+ ///
class function RotateLeft32(AValue: UInt32; AN: Int32): UInt32; static; inline;
+
+ ///
+ /// Rotates a 64-bit value left by AN positions.
+ /// Bits shifted out re-enter at the low-order end.
+ ///
class function RotateLeft64(AValue: UInt64; AN: Int32): UInt64; static; inline;
+
+ ///
+ /// Rotates an 8-bit value right by AN positions.
+ /// Bits shifted out re-enter at the high-order end.
+ ///
class function RotateRight8(AValue: Byte; AN: Int32): Byte; static; inline;
+
+ ///
+ /// Rotates a 16-bit value right by AN positions.
+ /// Bits shifted out re-enter at the high-order end.
+ ///
class function RotateRight16(AValue: UInt16; AN: Int32): UInt16; static; inline;
+
+ ///
+ /// Rotates a 32-bit value right by AN positions.
+ /// Bits shifted out re-enter at the high-order end.
+ ///
class function RotateRight32(AValue: UInt32; AN: Int32): UInt32; static; inline;
+
+ ///
+ /// Rotates a 64-bit value right by AN positions.
+ /// Bits shifted out re-enter at the high-order end.
+ ///
class function RotateRight64(AValue: UInt64; AN: Int32): UInt64; static; inline;
+ ///
+ /// Counts leading zero bits from the MSB down to the highest set bit.
+ /// Returns 32 when AValue is zero.
+ ///
class function NumberOfLeadingZeros32(AValue: UInt32): Int32; static;
+
+ ///
+ /// Counts leading zero bits from the MSB down to the highest set bit.
+ /// Returns 64 when AValue is zero.
+ ///
class function NumberOfLeadingZeros64(AValue: UInt64): Int32; static;
+ ///
+ /// Counts trailing zero bits from the LSB up to the lowest set bit.
+ /// Returns 32 when AValue is zero.
+ ///
class function NumberOfTrailingZeros32(AValue: UInt32): Int32; static;
+
+ ///
+ /// Counts trailing zero bits from the LSB up to the lowest set bit.
+ /// Returns 64 when AValue is zero.
+ ///
class function NumberOfTrailingZeros64(AValue: UInt64): Int32; static;
+ ///
+ /// Population count (Hamming weight) of a 32-bit value.
+ /// Returns the number of bits set to 1.
+ ///
class function PopCount32(AValue: UInt32): Int32; static;
+
+ ///
+ /// Population count (Hamming weight) of a 64-bit value.
+ /// Returns the number of bits set to 1.
+ ///
class function PopCount64(AValue: UInt64): Int32; static;
end;
implementation
-{ TBitUtilities }
+{ TBitOperations }
class function TBitOperations.ReverseBytesInt32(AValue: Int32): Int32;
{$IFNDEF FPC}
diff --git a/CryptoLib/src/NumberUtilities/ClpByteUtilities.pas b/CryptoLib/src/NumberUtilities/ClpByteUtilities.pas
index e673051e..d302df4f 100644
--- a/CryptoLib/src/NumberUtilities/ClpByteUtilities.pas
+++ b/CryptoLib/src/NumberUtilities/ClpByteUtilities.pas
@@ -22,6 +22,7 @@ interface
uses
ClpNat,
+ ClpBinaryPrimitives,
ClpCryptoLibTypes;
type
@@ -35,10 +36,19 @@ TByteUtilities = class sealed(TObject)
class procedure &Xor(ALen: Int32; const AX: TCryptoLibByteArray; AXOff: Int32;
const AY: TCryptoLibByteArray; AYOff: Int32;
const AZ: TCryptoLibByteArray; AZOff: Int32); overload; static;
+ ///
+ /// Triple-XOR: AZ := AX xor AY. Intentionally NOT inline: FPC 3.2 for
+ /// i386 miscompiles the equivalent loop when inlined inside pipelined
+ /// GCM steps at -O3, so the CALL boundary is load-bearing.
+ ///
+ class procedure &Xor(ALen: Int32; AX, AY, AZ: PByte); overload; static;
+ class procedure &Xor(ALen: Int32; AX, AY, AZ: PByte; AXOff, AYOff, AZOff: Integer); overload; static;
class procedure XorTo(ALen: Int32; const AX, AZ: TCryptoLibByteArray); overload; static;
class procedure XorTo(ALen: Int32; const AX: TCryptoLibByteArray; AXOff: Int32;
const AZ: TCryptoLibByteArray; AZOff: Int32); overload; static;
+ class procedure XorTo(ALen: Int32; AX, AZ: PByte); overload; static;
+ class procedure XorTo(ALen: Int32; AX, AZ: PByte; AXOff, AZOff: Integer); overload; static;
class procedure CMov(ALen: Int32; ACond: Int32; const AX, AZ: TCryptoLibByteArray); overload; static;
class procedure CMov(ALen: Int32; ACond: Int32; const AX: TCryptoLibByteArray; AXOff: Int32;
@@ -49,47 +59,91 @@ implementation
{ TByteUtilities }
-class procedure TByteUtilities.&Xor(ALen: Int32; const AX, AY, AZ: TCryptoLibByteArray);
+class procedure TByteUtilities.&Xor(ALen: Int32; AX, AY, AZ: PByte);
var
- LI: Int32;
+ LI, LQwords: Int32;
+ PSrcA, PSrcB, PDst: PByte;
begin
- for LI := 0 to ALen - 1 do
+ if ALen <= 0 then
+ Exit;
+
+ PSrcA := AX;
+ PSrcB := AY;
+ PDst := AZ;
+
+ if (ALen >= 8) and
+ ((NativeUInt(PSrcA) or NativeUInt(PSrcB) or NativeUInt(PDst) or NativeUInt(ALen)) and 7 = 0) then
begin
- AZ[LI] := Byte(AX[LI] xor AY[LI]);
+ LQwords := ALen shr 3;
+ for LI := 0 to LQwords - 1 do
+ TBinaryPrimitives.StoreUInt64(PUInt64(PDst + (LI * 8)),
+ TBinaryPrimitives.LoadUInt64(PUInt64(PSrcA + (LI * 8))) xor
+ TBinaryPrimitives.LoadUInt64(PUInt64(PSrcB + (LI * 8))));
+ Exit;
end;
+
+ for LI := 0 to ALen - 1 do
+ PDst[LI] := Byte(PSrcA[LI] xor PSrcB[LI]);
+end;
+
+class procedure TByteUtilities.&Xor(ALen: Int32; AX, AY, AZ: PByte;
+ AXOff, AYOff, AZOff: Integer);
+begin
+ &Xor(ALen, AX + AXOff, AY + AYOff, AZ + AZOff);
+end;
+
+class procedure TByteUtilities.&Xor(ALen: Int32; const AX, AY, AZ: TCryptoLibByteArray);
+begin
+ &Xor(ALen, PByte(AX), PByte(AY), PByte(AZ));
end;
class procedure TByteUtilities.&Xor(ALen: Int32; const AX: TCryptoLibByteArray; AXOff: Int32;
const AY: TCryptoLibByteArray; AYOff: Int32;
const AZ: TCryptoLibByteArray; AZOff: Int32);
+begin
+ &Xor(ALen, PByte(AX), PByte(AY), PByte(AZ), AXOff, AYOff, AZOff);
+end;
+
+class procedure TByteUtilities.XorTo(ALen: Int32; AX, AZ: PByte);
var
- LI: Int32;
+ LI, LQwords: Int32;
+ PSrc, PDst: PByte;
begin
- for LI := 0 to ALen - 1 do
+ if ALen <= 0 then
+ Exit;
+
+ PSrc := AX;
+ PDst := AZ;
+
+ if (ALen >= 8) and
+ ((NativeUInt(PSrc) or NativeUInt(PDst) or NativeUInt(ALen)) and 7 = 0) then
begin
- AZ[AZOff + LI] := Byte(AX[AXOff + LI] xor AY[AYOff + LI]);
+ LQwords := ALen shr 3;
+ for LI := 0 to LQwords - 1 do
+ TBinaryPrimitives.StoreUInt64(PUInt64(PDst + (LI * 8)),
+ TBinaryPrimitives.LoadUInt64(PUInt64(PDst + (LI * 8))) xor
+ TBinaryPrimitives.LoadUInt64(PUInt64(PSrc + (LI * 8))));
+ Exit;
end;
+
+ for LI := 0 to ALen - 1 do
+ PDst[LI] := PDst[LI] xor PSrc[LI];
+end;
+
+class procedure TByteUtilities.XorTo(ALen: Int32; AX, AZ: PByte; AXOff, AZOff: Integer);
+begin
+ XorTo(ALen, AX + AXOff, AZ + AZOff);
end;
class procedure TByteUtilities.XorTo(ALen: Int32; const AX, AZ: TCryptoLibByteArray);
-var
- LI: Int32;
begin
- for LI := 0 to ALen - 1 do
- begin
- AZ[LI] := AZ[LI] xor AX[LI];
- end;
+ XorTo(ALen, PByte(AX), PByte(AZ));
end;
class procedure TByteUtilities.XorTo(ALen: Int32; const AX: TCryptoLibByteArray; AXOff: Int32;
const AZ: TCryptoLibByteArray; AZOff: Int32);
-var
- LI: Int32;
begin
- for LI := 0 to ALen - 1 do
- begin
- AZ[AZOff + LI] := AZ[AZOff + LI] xor AX[AXOff + LI];
- end;
+ XorTo(ALen, PByte(AX), PByte(AZ), AXOff, AZOff);
end;
class procedure TByteUtilities.CMov(ALen: Int32; ACond: Int32; const AX, AZ: TCryptoLibByteArray);
diff --git a/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk b/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
index a4fe0c19..a324400a 100644
--- a/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
+++ b/CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
@@ -334,7 +334,24 @@ contains
ClpKeyGenerationParameters in '..\..\Crypto\Parameters\ClpKeyGenerationParameters.pas',
ClpKeyParameter in '..\..\Crypto\Parameters\ClpKeyParameter.pas',
ClpKMac in '..\..\Crypto\Macs\ClpKMac.pas',
- ClpLongArray in '..\..\Math\EC\ClpLongArray.pas',
+ ClpIBinPolyMul in '..\..\Interfaces\Math\BinPoly\ClpIBinPolyMul.pas',
+ ClpIBinPolyInv in '..\..\Interfaces\Math\BinPoly\ClpIBinPolyInv.pas',
+ ClpBinPolyMulBaseBinomialReduce in '..\..\Math\BinPoly\MulBase\ClpBinPolyMulBaseBinomialReduce.pas',
+ ClpBinPolyMulBaseTrinomialReduce in '..\..\Math\BinPoly\MulBase\ClpBinPolyMulBaseTrinomialReduce.pas',
+ ClpBinPolyMulBasePentanomialReduce in '..\..\Math\BinPoly\MulBase\ClpBinPolyMulBasePentanomialReduce.pas',
+ ClpBinPolyScalarKernels in '..\..\Math\BinPoly\Scalar\ClpBinPolyScalarKernels.pas',
+ ClpBinPolyScalarMedium in '..\..\Math\BinPoly\Scalar\ClpBinPolyScalarMedium.pas',
+ ClpBinPolyScalarLarge in '..\..\Math\BinPoly\Scalar\ClpBinPolyScalarLarge.pas',
+ ClpBinPolyScalarBackend in '..\..\Math\BinPoly\Scalar\ClpBinPolyScalarBackend.pas',
+ ClpBinPolyX86V128Kernels in '..\..\Math\BinPoly\X86\V128\ClpBinPolyX86V128Kernels.pas',
+ ClpBinPolyX86V128Medium in '..\..\Math\BinPoly\X86\V128\ClpBinPolyX86V128Medium.pas',
+ ClpBinPolyX86V128Large in '..\..\Math\BinPoly\X86\V128\ClpBinPolyX86V128Large.pas',
+ ClpBinPolyX86V128Backend in '..\..\Math\BinPoly\X86\V128\ClpBinPolyX86V128Backend.pas',
+ ClpBinPolyMulBase in '..\..\Math\BinPoly\ClpBinPolyMulBase.pas',
+ ClpItohTsujiiInv in '..\..\Math\BinPoly\ClpItohTsujiiInv.pas',
+ ClpBinPolys in '..\..\Math\BinPoly\ClpBinPolys.pas',
+ ClpIF2mFieldData in '..\..\Interfaces\Math\EC\ClpIF2mFieldData.pas',
+ ClpF2mFieldData in '..\..\Math\EC\ClpF2mFieldData.pas',
ClpMacUtilities in '..\..\Crypto\Macs\ClpMacUtilities.pas',
ClpMacSink in '..\..\Crypto\IO\ClpMacSink.pas',
ClpMacStream in '..\..\Crypto\IO\ClpMacStream.pas',
diff --git a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
index 1b069d1b..acf9fa07 100644
--- a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
+++ b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
@@ -10,7 +10,7 @@
-
+
@@ -26,7 +26,7 @@
Acknowledgements:
Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
-
+
@@ -100,2722 +100,2794 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
-
-
-
-
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
index 74f0598f..bed6bde2 100644
--- a/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
+++ b/CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
@@ -13,7 +13,7 @@ interface
ClpSecNamedCurves, ClpSecObjectIdentifiers, ClpTeleTrusTObjectIdentifiers,
ClpECNamedCurveTable, ClpX9ObjectIdentifiers, ClpAsymmetricCipherKeyPair,
ClpParametersWithRandom, ClpDsaDigestSigner, ClpECDsaSigner,
- ClpECAlgorithms, ClpLongArray, ClpSimpleBigDecimal, ClpTnaf, ClpZTauElement,
+ ClpECAlgorithms, ClpSimpleBigDecimal, ClpTnaf, ClpZTauElement,
ClpGlvTypeBEndomorphism, ClpGlvTypeBParameters, ClpFixedPointPreCompInfo,
ClpWNafPreCompInfo, ClpWTauNafPreCompInfo, ClpFiniteFields,
ClpGenericPolynomialExtensionField, ClpGF2Polynomial, ClpPrimeField, ClpMod,
@@ -227,7 +227,13 @@ interface
ClpDigestStream, ClpMacSink, ClpMacStream, ClpSignerStream,
ClpDefaultMacCalculator, ClpDefaultMacResult, ClpIMacAlgorithmFinder,
ClpDefaultMacAlgorithmFinder, ClpISignatureAlgorithmFinder,
- ClpDefaultSignatureAlgorithmFinder;
+ ClpDefaultSignatureAlgorithmFinder, ClpIBinPolyMul, ClpIF2mFieldData,
+ ClpBinPolyMulBase, ClpBinPolys, ClpItohTsujiiInv, ClpF2mFieldData,
+ ClpIBinPolyInv, ClpBinPolyX86V128Backend, ClpBinPolyX86V128Kernels,
+ ClpBinPolyX86V128Large, ClpBinPolyX86V128Medium, ClpBinPolyX86V128Sizes,
+ ClpBinPolyScalarBackend, ClpBinPolyScalarKernels, ClpBinPolyScalarLarge,
+ ClpBinPolyScalarMedium, ClpBinPolyMulBaseBinomialReduce,
+ ClpBinPolyMulBasePentanomialReduce, ClpBinPolyMulBaseTrinomialReduce;
implementation
diff --git a/CryptoLib/src/Pkcs/ClpPkcs10CertificationRequest.pas b/CryptoLib/src/Pkcs/ClpPkcs10CertificationRequest.pas
index a9f40a57..c3726098 100644
--- a/CryptoLib/src/Pkcs/ClpPkcs10CertificationRequest.pas
+++ b/CryptoLib/src/Pkcs/ClpPkcs10CertificationRequest.pas
@@ -77,7 +77,6 @@ TPkcs10CertificationRequest = class(TCertificationRequest, IPkcs10Certificatio
FExParams: TDictionary;
FNoParams: TDictionary;
FKeyAlgorithms: TDictionary;
- class procedure Boot; static;
class function CreatePssParams(const AHashAlgId: IAlgorithmIdentifier;
ASaltSize: Int32): IRsassaPssParameters; static;
class constructor Create;
@@ -117,29 +116,6 @@ implementation
{ TPkcs10CertificationRequest }
class constructor TPkcs10CertificationRequest.Create;
-begin
- Boot;
-end;
-
-class destructor TPkcs10CertificationRequest.Destroy;
-begin
- FAlgorithms.Free;
- FExParams.Free;
- FNoParams.Free;
- FKeyAlgorithms.Free;
-end;
-
-class function TPkcs10CertificationRequest.CreatePssParams(const AHashAlgId: IAlgorithmIdentifier;
- ASaltSize: Int32): IRsassaPssParameters;
-var
- LMgfAlgId: IAlgorithmIdentifier;
-begin
- LMgfAlgId := TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdMgf1, AHashAlgId);
- Result := TRsassaPssParameters.Create(AHashAlgId, LMgfAlgId,
- TDerInteger.ValueOf(ASaltSize), TRsassaPssParameters.DefaultTrailerField);
-end;
-
-class procedure TPkcs10CertificationRequest.Boot;
var
LSha1AlgId, LSha224AlgId, LSha256AlgId, LSha384AlgId, LSha512AlgId: IAlgorithmIdentifier;
begin
@@ -287,6 +263,24 @@ class procedure TPkcs10CertificationRequest.Boot;
FExParams.Add('SHA512WITHRSAANDMGF1', CreatePssParams(LSha512AlgId, 64));
end;
+class destructor TPkcs10CertificationRequest.Destroy;
+begin
+ FAlgorithms.Free;
+ FExParams.Free;
+ FNoParams.Free;
+ FKeyAlgorithms.Free;
+end;
+
+class function TPkcs10CertificationRequest.CreatePssParams(const AHashAlgId: IAlgorithmIdentifier;
+ ASaltSize: Int32): IRsassaPssParameters;
+var
+ LMgfAlgId: IAlgorithmIdentifier;
+begin
+ LMgfAlgId := TAlgorithmIdentifier.Create(TPkcsObjectIdentifiers.IdMgf1, AHashAlgId);
+ Result := TRsassaPssParameters.Create(AHashAlgId, LMgfAlgId,
+ TDerInteger.ValueOf(ASaltSize), TRsassaPssParameters.DefaultTrailerField);
+end;
+
constructor TPkcs10CertificationRequest.Create(const AEncoded: TCryptoLibByteArray);
begin
inherited Create(TAsn1Sequence.GetInstance(AEncoded));
diff --git a/CryptoLib/src/Pkcs/ClpPkcs12Store.pas b/CryptoLib/src/Pkcs/ClpPkcs12Store.pas
index f6c00748..2a2604e0 100644
--- a/CryptoLib/src/Pkcs/ClpPkcs12Store.pas
+++ b/CryptoLib/src/Pkcs/ClpPkcs12Store.pas
@@ -140,7 +140,6 @@ TCertID = record
FKeySaltSize: Int32;
FCertSaltSize: Int32;
FMacSaltSize: Int32;
- FUnmarkedKeyEntry: IAsymmetricKeyEntry;
strict private
procedure ClearKeys;
procedure ClearCerts;
@@ -174,9 +173,11 @@ TCertID = record
function GetCount: Int32;
function GetAliases: TCryptoLibStringArray;
- procedure LoadKeyBag(const APrivKeyInfo: IPrivateKeyInfo; const ABagAttributes: IAsn1Set); virtual;
+ procedure LoadKeyBag(const APrivKeyInfo: IPrivateKeyInfo; const ABagAttributes: IAsn1Set;
+ var AUnmarkedKeyEntry: IAsymmetricKeyEntry); virtual;
procedure LoadPkcs8ShroudedKeyBag(const AEncPrivKeyInfo: IEncryptedPrivateKeyInfo;
- const ABagAttributes: IAsn1Set; const APassword: TCryptoLibCharArray; AWrongPkcs12Zero: Boolean); virtual;
+ const ABagAttributes: IAsn1Set; const APassword: TCryptoLibCharArray; AWrongPkcs12Zero: Boolean;
+ var AUnmarkedKeyEntry: IAsymmetricKeyEntry); virtual;
public
const
DefaultIterations = 1024;
@@ -582,7 +583,8 @@ class function TPkcs12Store.CryptPbeData(AForEncryption: Boolean; const AAlgID:
Result := LCipher.DoFinal(AData);
end;
-procedure TPkcs12Store.LoadKeyBag(const APrivKeyInfo: IPrivateKeyInfo; const ABagAttributes: IAsn1Set);
+procedure TPkcs12Store.LoadKeyBag(const APrivKeyInfo: IPrivateKeyInfo; const ABagAttributes: IAsn1Set;
+ var AUnmarkedKeyEntry: IAsymmetricKeyEntry);
var
LKey: IAsymmetricKeyParameter;
LAttributes: TDictionary;
@@ -637,16 +639,17 @@ procedure TPkcs12Store.LoadKeyBag(const APrivKeyInfo: IPrivateKeyInfo; const ABa
FLocalIDs.AddOrSetValue(LAlias, LName);
end
else
- FUnmarkedKeyEntry := LKeyEntry;
+ AUnmarkedKeyEntry := LKeyEntry;
end;
procedure TPkcs12Store.LoadPkcs8ShroudedKeyBag(const AEncPrivKeyInfo: IEncryptedPrivateKeyInfo;
- const ABagAttributes: IAsn1Set; const APassword: TCryptoLibCharArray; AWrongPkcs12Zero: Boolean);
+ const ABagAttributes: IAsn1Set; const APassword: TCryptoLibCharArray; AWrongPkcs12Zero: Boolean;
+ var AUnmarkedKeyEntry: IAsymmetricKeyEntry);
var
LPrivateKeyInfo: IPrivateKeyInfo;
begin
LPrivateKeyInfo := TPrivateKeyInfoFactory.CreatePrivateKeyInfo(APassword, AWrongPkcs12Zero, AEncPrivKeyInfo);
- LoadKeyBag(LPrivateKeyInfo, ABagAttributes);
+ LoadKeyBag(LPrivateKeyInfo, ABagAttributes, AUnmarkedKeyEntry);
end;
procedure TPkcs12Store.Load(const AInput: TStream; const APassword: TCryptoLibCharArray);
@@ -686,6 +689,7 @@ procedure TPkcs12Store.Load(const AInput: TStream; const APassword: TCryptoLibCh
LCertEntry: IX509CertificateEntry;
LName: String;
LIgnore: Boolean;
+ LUnmarkedKeyEntry: IAsymmetricKeyEntry;
begin
if AInput = nil then
raise EArgumentNilCryptoLibException.Create(SInputNil);
@@ -713,7 +717,7 @@ procedure TPkcs12Store.Load(const AInput: TStream; const APassword: TCryptoLibCh
end;
ClearKeys;
FLocalIDs.Clear;
- FUnmarkedKeyEntry := nil;
+ LUnmarkedKeyEntry := nil;
LCertBags := TList.Create;
try
if TPkcsObjectIdentifiers.Data.Equals(LInfo.ContentType) then
@@ -745,12 +749,13 @@ procedure TPkcs12Store.Load(const AInput: TStream; const APassword: TCryptoLibCh
if TPkcsObjectIdentifiers.CertBag.Equals(LSafeBagID) then
LCertBags.Add(LSafeBag)
else if TPkcsObjectIdentifiers.KeyBag.Equals(LSafeBagID) then
- LoadKeyBag(TPrivateKeyInfo.GetInstance(LSafeBag.BagValueEncodable), LSafeBag.BagAttributes)
+ LoadKeyBag(TPrivateKeyInfo.GetInstance(LSafeBag.BagValueEncodable), LSafeBag.BagAttributes,
+ LUnmarkedKeyEntry)
else if TPkcsObjectIdentifiers.Pkcs8ShroudedKeyBag.Equals(LSafeBagID) then
begin
LPasswordNeeded := True;
LoadPkcs8ShroudedKeyBag(TEncryptedPrivateKeyInfo.GetInstance(LSafeBag.BagValueEncodable),
- LSafeBag.BagAttributes, APassword, LWrongPkcs12Zero);
+ LSafeBag.BagAttributes, APassword, LWrongPkcs12Zero, LUnmarkedKeyEntry);
end;
end;
end;
@@ -799,16 +804,15 @@ procedure TPkcs12Store.Load(const AInput: TStream; const APassword: TCryptoLibCh
LCertID := TCertID.Create(LCert);
LCertEntry := TX509CertificateEntry.Create(LCert, LAttributes);
MapChainCert(LCertID, LCertEntry);
- if FUnmarkedKeyEntry <> nil then
+ if LUnmarkedKeyEntry <> nil then
begin
if FKeyCerts.Count = 0 then
begin
LName := THexEncoder.Encode(LCertID.Id);
FKeyCerts.Add(LName, LCertEntry);
- MapKey(LName, FUnmarkedKeyEntry);
- end
- else
- MapKey('unmarked', FUnmarkedKeyEntry);
+ MapKey(LName, LUnmarkedKeyEntry);
+ end;
+ LUnmarkedKeyEntry := nil;
end
else
begin
@@ -821,6 +825,8 @@ procedure TPkcs12Store.Load(const AInput: TStream; const APassword: TCryptoLibCh
MapCert(LAlias, LCertEntry);
end;
end;
+ if LUnmarkedKeyEntry <> nil then
+ MapKey('unmarked', LUnmarkedKeyEntry);
if not LPasswordNeeded and (APassword <> nil) then
begin
LIgnore := FIgnoreUselessPassword;
diff --git a/CryptoLib/src/Rngs/Providers/ClpAesRandomProvider.pas b/CryptoLib/src/Rngs/Providers/ClpAesRandomProvider.pas
index f38aec2c..8c95bf0b 100644
--- a/CryptoLib/src/Rngs/Providers/ClpAesRandomProvider.pas
+++ b/CryptoLib/src/Rngs/Providers/ClpAesRandomProvider.pas
@@ -62,8 +62,6 @@ TAesRandomProvider = class sealed(TBaseRandomProvider)
class function OsProviderAvailable: Boolean; static;
class procedure GetRawEntropy(const AEntropy: TCryptoLibByteArray); inline;
-
- class procedure Boot(); static;
class constructor Create();
class destructor Destroy();
@@ -151,18 +149,9 @@ class procedure TAesRandomProvider.GetRawEntropy(
TOSRandomProvider.Instance.GetBytes(AEntropy);
end;
-class procedure TAesRandomProvider.Boot;
-begin
- if FLock = nil then
- begin
- FLock := TCriticalSection.Create;
- end;
- GetInstance;
-end;
-
class constructor TAesRandomProvider.Create();
begin
- Boot();
+ FLock := TCriticalSection.Create;
end;
class destructor TAesRandomProvider.Destroy();
diff --git a/CryptoLib/src/Rngs/Providers/ClpOSRandomProvider.pas b/CryptoLib/src/Rngs/Providers/ClpOSRandomProvider.pas
index 66696a58..7e4c2fa5 100644
--- a/CryptoLib/src/Rngs/Providers/ClpOSRandomProvider.pas
+++ b/CryptoLib/src/Rngs/Providers/ClpOSRandomProvider.pas
@@ -60,16 +60,12 @@ TOSRandomProvider = class sealed(TObject)
class var
FInstance: IRandomSourceProvider;
FLock: TCriticalSection;
- FIsBooted: Boolean;
class function GetInstance: IRandomSourceProvider; static;
class function CreateProvider: IRandomSourceProvider; static;
public
class property Instance: IRandomSourceProvider read GetInstance;
-
- class procedure Boot(); static;
-
class constructor Create();
class destructor Destroy();
@@ -82,7 +78,13 @@ implementation
class constructor TOSRandomProvider.Create();
begin
- Boot();
+ FLock := TCriticalSection.Create;
+ FLock.Enter;
+ try
+ FInstance := CreateProvider();
+ finally
+ FLock.Leave;
+ end;
end;
class destructor TOSRandomProvider.Destroy();
@@ -120,19 +122,4 @@ class function TOSRandomProvider.GetInstance: IRandomSourceProvider;
Result := FInstance;
end;
-class procedure TOSRandomProvider.Boot;
-begin
- if not FIsBooted then
- begin
- FLock := TCriticalSection.Create;
- FLock.Enter;
- try
- FInstance := CreateProvider();
- finally
- FLock.Leave;
- end;
- FIsBooted := True;
- end;
-end;
-
end.
diff --git a/CryptoLib/src/X509/ClpX509AttrCertParser.pas b/CryptoLib/src/X509/ClpX509AttrCertParser.pas
index 97401e43..0bc059aa 100644
--- a/CryptoLib/src/X509/ClpX509AttrCertParser.pas
+++ b/CryptoLib/src/X509/ClpX509AttrCertParser.pas
@@ -61,7 +61,6 @@ TX509AttrCertParser = class sealed(TInterfacedObject, IX509AttrCertParser)
FCurrentStream: TStream;
class constructor Create();
- class procedure Boot();
class function GetTaggedPkcsSignedData(ATagged: IAsn1TaggedObject; AState: Boolean): IPkcsSignedData; static;
class function GetTaggedAttributeCertificate(ATagged: IAsn1TaggedObject; AState: Boolean): IAttributeCertificate; static;
@@ -85,11 +84,6 @@ implementation
{ TX509AttrCertParser }
class constructor TX509AttrCertParser.Create();
-begin
- Boot();
-end;
-
-class procedure TX509AttrCertParser.Boot();
begin
FPemAttrCertParser := TPemParser.Create('ATTRIBUTE CERTIFICATE');
end;
diff --git a/CryptoLib/src/X509/ClpX509CertificateParser.pas b/CryptoLib/src/X509/ClpX509CertificateParser.pas
index 4e83d2c4..f08c3c52 100644
--- a/CryptoLib/src/X509/ClpX509CertificateParser.pas
+++ b/CryptoLib/src/X509/ClpX509CertificateParser.pas
@@ -60,7 +60,6 @@ TX509CertificateParser = class sealed(TInterfacedObject, IX509CertificateParse
FCurrentStream: TStream;
class constructor Create();
- class procedure Boot();
class function GetTaggedPkcsSignedData(ATagged: IAsn1TaggedObject; AState: Boolean): IPkcsSignedData; static;
function ReadDerCertificate(const ADIn: TAsn1InputStream): IX509Certificate;
@@ -83,11 +82,6 @@ implementation
{ TX509CertificateParser }
class constructor TX509CertificateParser.Create();
-begin
- Boot();
-end;
-
-class procedure TX509CertificateParser.Boot();
begin
FPemCertParser := TPemParser.Create('CERTIFICATE');
end;
diff --git a/CryptoLib/src/X509/ClpX509CrlParser.pas b/CryptoLib/src/X509/ClpX509CrlParser.pas
index 18a7863a..f6914daa 100644
--- a/CryptoLib/src/X509/ClpX509CrlParser.pas
+++ b/CryptoLib/src/X509/ClpX509CrlParser.pas
@@ -54,7 +54,6 @@ TX509CrlParser = class sealed(TInterfacedObject, IX509CrlParser)
FCurrentCrlStream: TStream;
class constructor Create();
- class procedure Boot();
class function GetTaggedPkcsSignedData(ATagged: IAsn1TaggedObject; AState: Boolean): IPkcsSignedData; static;
function ReadDerCrl(const ADIn: TAsn1InputStream): IX509Crl;
@@ -77,11 +76,6 @@ implementation
{ TX509CrlParser }
class constructor TX509CrlParser.Create();
-begin
- Boot();
-end;
-
-class procedure TX509CrlParser.Boot();
begin
FPemCrlParser := TPemParser.Create('CRL');
end;
diff --git a/CryptoLib/src/X509/ClpX509Utilities.pas b/CryptoLib/src/X509/ClpX509Utilities.pas
index ec066970..e07f738e 100644
--- a/CryptoLib/src/X509/ClpX509Utilities.pas
+++ b/CryptoLib/src/X509/ClpX509Utilities.pas
@@ -61,8 +61,6 @@ TX509Utilities = class sealed(TObject)
strict private
class var
FAlgorithms: TDictionary;
-
- class procedure Boot; static;
class constructor Create;
class destructor Destroy;
@@ -107,16 +105,6 @@ implementation
{ TX509Utilities }
class constructor TX509Utilities.Create;
-begin
- Boot;
-end;
-
-class destructor TX509Utilities.Destroy;
-begin
- FAlgorithms.Free;
-end;
-
-class procedure TX509Utilities.Boot;
begin
FAlgorithms := TDictionary.Create(TCryptoLibComparers.OrdinalIgnoreCaseEqualityComparer);
@@ -209,6 +197,11 @@ class procedure TX509Utilities.Boot;
FAlgorithms.Add('GOST3411WITHGOST3410-2001', TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
end;
+class destructor TX509Utilities.Destroy;
+begin
+ FAlgorithms.Free;
+end;
+
class function TX509Utilities.AreEquivalentAlgorithms(const AId1, AId2: IAlgorithmIdentifier): Boolean;
begin
if not AId1.Algorithm.Equals(AId2.Algorithm) then