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