Add CRC-32C using CXX and SSE4 (Issue 160)

pull/161/head
Jeffrey Walton 2016-04-24 13:24:45 -04:00
parent 87d81372a9
commit bf22c4575b
7 changed files with 234 additions and 8 deletions

View File

@ -309,6 +309,7 @@ void BenchmarkAll(double t, double hertz)
cout << "\n<TBODY style=\"background: yellow\">";
BenchMarkByNameKeyLess<HashTransformation>("CRC32");
BenchMarkByNameKeyLess<HashTransformation>("CRC32C");
BenchMarkByNameKeyLess<HashTransformation>("Adler32");
BenchMarkByNameKeyLess<HashTransformation>("MD5");
BenchMarkByNameKeyLess<HashTransformation>("SHA-1");

176
crc.cpp
View File

@ -3,9 +3,16 @@
#include "pch.h"
#include "crc.h"
#include "misc.h"
#include "cpu.h"
NAMESPACE_BEGIN(CryptoPP)
// Visual Studio needs VS2008 (1500)
// http://msdn.microsoft.com/en-us/library/bb531394%28v=vs.90%29.aspx
#if defined(_MSC_VER) && (_MSC_VER < 1500)
# undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
#endif
/* Table of CRC-32's of all single byte values (made by makecrc.c) */
const word32 CRC32::m_tab[] = {
#ifdef IS_LITTLE_ENDIAN
@ -158,4 +165,173 @@ void CRC32::TruncatedFinal(byte *hash, size_t size)
Reset();
}
// Castagnoli CRC32C (iSCSI)
const word32 CRC32C::m_tab[] = {
#ifdef IS_LITTLE_ENDIAN
0x00000000L, 0xf26b8303L, 0xe13b70f7L, 0x1350f3f4L, 0xc79a971fL,
0x35f1141cL, 0x26a1e7e8L, 0xd4ca64ebL, 0x8ad958cfL, 0x78b2dbccL,
0x6be22838L, 0x9989ab3bL, 0x4d43cfd0L, 0xbf284cd3L, 0xac78bf27L,
0x5e133c24L, 0x105ec76fL, 0xe235446cL, 0xf165b798L, 0x030e349bL,
0xd7c45070L, 0x25afd373L, 0x36ff2087L, 0xc494a384L, 0x9a879fa0L,
0x68ec1ca3L, 0x7bbcef57L, 0x89d76c54L, 0x5d1d08bfL, 0xaf768bbcL,
0xbc267848L, 0x4e4dfb4bL, 0x20bd8edeL, 0xd2d60dddL, 0xc186fe29L,
0x33ed7d2aL, 0xe72719c1L, 0x154c9ac2L, 0x061c6936L, 0xf477ea35L,
0xaa64d611L, 0x580f5512L, 0x4b5fa6e6L, 0xb93425e5L, 0x6dfe410eL,
0x9f95c20dL, 0x8cc531f9L, 0x7eaeb2faL, 0x30e349b1L, 0xc288cab2L,
0xd1d83946L, 0x23b3ba45L, 0xf779deaeL, 0x05125dadL, 0x1642ae59L,
0xe4292d5aL, 0xba3a117eL, 0x4851927dL, 0x5b016189L, 0xa96ae28aL,
0x7da08661L, 0x8fcb0562L, 0x9c9bf696L, 0x6ef07595L, 0x417b1dbcL,
0xb3109ebfL, 0xa0406d4bL, 0x522bee48L, 0x86e18aa3L, 0x748a09a0L,
0x67dafa54L, 0x95b17957L, 0xcba24573L, 0x39c9c670L, 0x2a993584L,
0xd8f2b687L, 0x0c38d26cL, 0xfe53516fL, 0xed03a29bL, 0x1f682198L,
0x5125dad3L, 0xa34e59d0L, 0xb01eaa24L, 0x42752927L, 0x96bf4dccL,
0x64d4cecfL, 0x77843d3bL, 0x85efbe38L, 0xdbfc821cL, 0x2997011fL,
0x3ac7f2ebL, 0xc8ac71e8L, 0x1c661503L, 0xee0d9600L, 0xfd5d65f4L,
0x0f36e6f7L, 0x61c69362L, 0x93ad1061L, 0x80fde395L, 0x72966096L,
0xa65c047dL, 0x5437877eL, 0x4767748aL, 0xb50cf789L, 0xeb1fcbadL,
0x197448aeL, 0x0a24bb5aL, 0xf84f3859L, 0x2c855cb2L, 0xdeeedfb1L,
0xcdbe2c45L, 0x3fd5af46L, 0x7198540dL, 0x83f3d70eL, 0x90a324faL,
0x62c8a7f9L, 0xb602c312L, 0x44694011L, 0x5739b3e5L, 0xa55230e6L,
0xfb410cc2L, 0x092a8fc1L, 0x1a7a7c35L, 0xe811ff36L, 0x3cdb9bddL,
0xceb018deL, 0xdde0eb2aL, 0x2f8b6829L, 0x82f63b78L, 0x709db87bL,
0x63cd4b8fL, 0x91a6c88cL, 0x456cac67L, 0xb7072f64L, 0xa457dc90L,
0x563c5f93L, 0x082f63b7L, 0xfa44e0b4L, 0xe9141340L, 0x1b7f9043L,
0xcfb5f4a8L, 0x3dde77abL, 0x2e8e845fL, 0xdce5075cL, 0x92a8fc17L,
0x60c37f14L, 0x73938ce0L, 0x81f80fe3L, 0x55326b08L, 0xa759e80bL,
0xb4091bffL, 0x466298fcL, 0x1871a4d8L, 0xea1a27dbL, 0xf94ad42fL,
0x0b21572cL, 0xdfeb33c7L, 0x2d80b0c4L, 0x3ed04330L, 0xccbbc033L,
0xa24bb5a6L, 0x502036a5L, 0x4370c551L, 0xb11b4652L, 0x65d122b9L,
0x97baa1baL, 0x84ea524eL, 0x7681d14dL, 0x2892ed69L, 0xdaf96e6aL,
0xc9a99d9eL, 0x3bc21e9dL, 0xef087a76L, 0x1d63f975L, 0x0e330a81L,
0xfc588982L, 0xb21572c9L, 0x407ef1caL, 0x532e023eL, 0xa145813dL,
0x758fe5d6L, 0x87e466d5L, 0x94b49521L, 0x66df1622L, 0x38cc2a06L,
0xcaa7a905L, 0xd9f75af1L, 0x2b9cd9f2L, 0xff56bd19L, 0x0d3d3e1aL,
0x1e6dcdeeL, 0xec064eedL, 0xc38d26c4L, 0x31e6a5c7L, 0x22b65633L,
0xd0ddd530L, 0x0417b1dbL, 0xf67c32d8L, 0xe52cc12cL, 0x1747422fL,
0x49547e0bL, 0xbb3ffd08L, 0xa86f0efcL, 0x5a048dffL, 0x8ecee914L,
0x7ca56a17L, 0x6ff599e3L, 0x9d9e1ae0L, 0xd3d3e1abL, 0x21b862a8L,
0x32e8915cL, 0xc083125fL, 0x144976b4L, 0xe622f5b7L, 0xf5720643L,
0x07198540L, 0x590ab964L, 0xab613a67L, 0xb831c993L, 0x4a5a4a90L,
0x9e902e7bL, 0x6cfbad78L, 0x7fab5e8cL, 0x8dc0dd8fL, 0xe330a81aL,
0x115b2b19L, 0x020bd8edL, 0xf0605beeL, 0x24aa3f05L, 0xd6c1bc06L,
0xc5914ff2L, 0x37faccf1L, 0x69e9f0d5L, 0x9b8273d6L, 0x88d28022L,
0x7ab90321L, 0xae7367caL, 0x5c18e4c9L, 0x4f48173dL, 0xbd23943eL,
0xf36e6f75L, 0x0105ec76L, 0x12551f82L, 0xe03e9c81L, 0x34f4f86aL,
0xc69f7b69L, 0xd5cf889dL, 0x27a40b9eL, 0x79b737baL, 0x8bdcb4b9L,
0x988c474dL, 0x6ae7c44eL, 0xbe2da0a5L, 0x4c4623a6L, 0x5f16d052L,
0xad7d5351L
#else
0x00000000L, 0x03836bf2L, 0xf7703be1L, 0xf4f35013L, 0x1f979ac7L,
0x1c14f135L, 0xe8e7a126L, 0xeb64cad4L, 0xcf58d98aL, 0xccdbb278L,
0x3828e26bL, 0x3bab8999L, 0xd0cf434dL, 0xd34c28bfL, 0x27bf78acL,
0x243c135eL, 0x6fc75e10L, 0x6c4435e2L, 0x98b765f1L, 0x9b340e03L,
0x7050c4d7L, 0x73d3af25L, 0x8720ff36L, 0x84a394c4L, 0xa09f879aL,
0xa31cec68L, 0x57efbc7bL, 0x546cd789L, 0xbf081d5dL, 0xbc8b76afL,
0x487826bcL, 0x4bfb4d4eL, 0xde8ebd20L, 0xdd0dd6d2L, 0x29fe86c1L,
0x2a7ded33L, 0xc11927e7L, 0xc29a4c15L, 0x36691c06L, 0x35ea77f4L,
0x11d664aaL, 0x12550f58L, 0xe6a65f4bL, 0xe52534b9L, 0x0e41fe6dL,
0x0dc2959fL, 0xf931c58cL, 0xfab2ae7eL, 0xb149e330L, 0xb2ca88c2L,
0x4639d8d1L, 0x45bab323L, 0xaede79f7L, 0xad5d1205L, 0x59ae4216L,
0x5a2d29e4L, 0x7e113abaL, 0x7d925148L, 0x8961015bL, 0x8ae26aa9L,
0x6186a07dL, 0x6205cb8fL, 0x96f69b9cL, 0x9575f06eL, 0xbc1d7b41L,
0xbf9e10b3L, 0x4b6d40a0L, 0x48ee2b52L, 0xa38ae186L, 0xa0098a74L,
0x54fada67L, 0x5779b195L, 0x7345a2cbL, 0x70c6c939L, 0x8435992aL,
0x87b6f2d8L, 0x6cd2380cL, 0x6f5153feL, 0x9ba203edL, 0x9821681fL,
0xd3da2551L, 0xd0594ea3L, 0x24aa1eb0L, 0x27297542L, 0xcc4dbf96L,
0xcfced464L, 0x3b3d8477L, 0x38beef85L, 0x1c82fcdbL, 0x1f019729L,
0xebf2c73aL, 0xe871acc8L, 0x0315661cL, 0x00960deeL, 0xf4655dfdL,
0xf7e6360fL, 0x6293c661L, 0x6110ad93L, 0x95e3fd80L, 0x96609672L,
0x7d045ca6L, 0x7e873754L, 0x8a746747L, 0x89f70cb5L, 0xadcb1febL,
0xae487419L, 0x5abb240aL, 0x59384ff8L, 0xb25c852cL, 0xb1dfeedeL,
0x452cbecdL, 0x46afd53fL, 0x0d549871L, 0x0ed7f383L, 0xfa24a390L,
0xf9a7c862L, 0x12c302b6L, 0x11406944L, 0xe5b33957L, 0xe63052a5L,
0xc20c41fbL, 0xc18f2a09L, 0x357c7a1aL, 0x36ff11e8L, 0xdd9bdb3cL,
0xde18b0ceL, 0x2aebe0ddL, 0x29688b2fL, 0x783bf682L, 0x7bb89d70L,
0x8f4bcd63L, 0x8cc8a691L, 0x67ac6c45L, 0x642f07b7L, 0x90dc57a4L,
0x935f3c56L, 0xb7632f08L, 0xb4e044faL, 0x401314e9L, 0x43907f1bL,
0xa8f4b5cfL, 0xab77de3dL, 0x5f848e2eL, 0x5c07e5dcL, 0x17fca892L,
0x147fc360L, 0xe08c9373L, 0xe30ff881L, 0x086b3255L, 0x0be859a7L,
0xff1b09b4L, 0xfc986246L, 0xd8a47118L, 0xdb271aeaL, 0x2fd44af9L,
0x2c57210bL, 0xc733ebdfL, 0xc4b0802dL, 0x3043d03eL, 0x33c0bbccL,
0xa6b54ba2L, 0xa5362050L, 0x51c57043L, 0x52461bb1L, 0xb922d165L,
0xbaa1ba97L, 0x4e52ea84L, 0x4dd18176L, 0x69ed9228L, 0x6a6ef9daL,
0x9e9da9c9L, 0x9d1ec23bL, 0x767a08efL, 0x75f9631dL, 0x810a330eL,
0x828958fcL, 0xc97215b2L, 0xcaf17e40L, 0x3e022e53L, 0x3d8145a1L,
0xd6e58f75L, 0xd566e487L, 0x2195b494L, 0x2216df66L, 0x062acc38L,
0x05a9a7caL, 0xf15af7d9L, 0xf2d99c2bL, 0x19bd56ffL, 0x1a3e3d0dL,
0xeecd6d1eL, 0xed4e06ecL, 0xc4268dc3L, 0xc7a5e631L, 0x3356b622L,
0x30d5ddd0L, 0xdbb11704L, 0xd8327cf6L, 0x2cc12ce5L, 0x2f424717L,
0x0b7e5449L, 0x08fd3fbbL, 0xfc0e6fa8L, 0xff8d045aL, 0x14e9ce8eL,
0x176aa57cL, 0xe399f56fL, 0xe01a9e9dL, 0xabe1d3d3L, 0xa862b821L,
0x5c91e832L, 0x5f1283c0L, 0xb4764914L, 0xb7f522e6L, 0x430672f5L,
0x40851907L, 0x64b90a59L, 0x673a61abL, 0x93c931b8L, 0x904a5a4aL,
0x7b2e909eL, 0x78adfb6cL, 0x8c5eab7fL, 0x8fddc08dL, 0x1aa830e3L,
0x192b5b11L, 0xedd80b02L, 0xee5b60f0L, 0x053faa24L, 0x06bcc1d6L,
0xf24f91c5L, 0xf1ccfa37L, 0xd5f0e969L, 0xd673829bL, 0x2280d288L,
0x2103b97aL, 0xca6773aeL, 0xc9e4185cL, 0x3d17484fL, 0x3e9423bdL,
0x756f6ef3L, 0x76ec0501L, 0x821f5512L, 0x819c3ee0L, 0x6af8f434L,
0x697b9fc6L, 0x9d88cfd5L, 0x9e0ba427L, 0xba37b779L, 0xb9b4dc8bL,
0x4d478c98L, 0x4ec4e76aL, 0xa5a02dbeL, 0xa623464cL, 0x52d0165fL,
0x51537dadL
#endif
};
CRC32C::CRC32C()
{
Reset();
}
void CRC32C::Update(const byte *s, size_t n)
{
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
if (HasSSE4())
{
for(; !IsAligned<word32>(s) && n > 0; s++, n--)
m_crc = _mm_crc32_u8(m_crc, *s);
for(; n > 4; s+=4, n-=4)
m_crc = _mm_crc32_u32(m_crc, *(const word32 *)(void*)s);
for(; n > 0; s++, n--)
m_crc = _mm_crc32_u8(m_crc, *s);
return;
}
#endif
word32 crc = m_crc;
for(; !IsAligned<word32>(s) && n > 0; n--)
crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc);
assert((n && IsAlignedOn(s,GetAlignmentOf<word32>())) || !n);
while (n >= 4)
{
crc ^= *(const word32 *)(void*)s;
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
n -= 4;
s += 4;
}
while (n--)
crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc);
m_crc = crc;
}
void CRC32C::TruncatedFinal(byte *hash, size_t size)
{
ThrowIfInvalidTruncatedSize(size);
m_crc ^= CRC32_NEGL;
for (size_t i=0; i<size; i++)
hash[i] = GetCrcByte(i);
Reset();
}
NAMESPACE_END

32
crc.h
View File

@ -2,7 +2,7 @@
//! \file
//! \headerfile crc.h
//! \brief Classes for CRC-32 checksum algorithm
//! \brief Classes for CRC-32 and CRC-32C checksum algorithm
#ifndef CRYPTOPP_CRC32_H
#define CRYPTOPP_CRC32_H
@ -21,7 +21,8 @@ const word32 CRC32_NEGL = 0xffffffffL;
#define CRC32_SHIFTED(c) (c << 8)
#endif
//! CRC Checksum Calculation
//! \brief CRC-32 Checksum Calculation
//! \details Uses CRC polynomial 0xEDB88320
class CRC32 : public HashTransformation
{
public:
@ -36,9 +37,34 @@ public:
void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);}
byte GetCrcByte(size_t i) const {return ((byte *)&(m_crc))[i];}
private:
protected:
void Reset() {m_crc = CRC32_NEGL;}
private:
static const word32 m_tab[256];
word32 m_crc;
};
//! \brief CRC-32C Checksum Calculation
//! \details Uses CRC polynomial 0x82F63B78
class CRC32C : public HashTransformation
{
public:
CRYPTOPP_CONSTANT(DIGESTSIZE = 4)
CRC32C();
void Update(const byte *input, size_t length);
void TruncatedFinal(byte *hash, size_t size);
unsigned int DigestSize() const {return DIGESTSIZE;}
static const char * StaticAlgorithmName() {return "CRC32C";}
std::string AlgorithmName() const {return StaticAlgorithmName();}
void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);}
byte GetCrcByte(size_t i) const {return ((byte *)&(m_crc))[i];}
protected:
void Reset() {m_crc = CRC32_NEGL;}
private:
static const word32 m_tab[256];
word32 m_crc;
};

View File

@ -78,6 +78,7 @@ void RegisterFactories()
RegisterDefaultFactoryFor<SimpleKeyAgreementDomain, DH>();
RegisterDefaultFactoryFor<HashTransformation, CRC32>();
RegisterDefaultFactoryFor<HashTransformation, CRC32C>();
RegisterDefaultFactoryFor<HashTransformation, Adler32>();
RegisterDefaultFactoryFor<HashTransformation, Weak::MD5>();
RegisterDefaultFactoryFor<HashTransformation, SHA1>();
@ -97,6 +98,8 @@ void RegisterFactories()
RegisterDefaultFactoryFor<HashTransformation, SHA3_256>();
RegisterDefaultFactoryFor<HashTransformation, SHA3_384>();
RegisterDefaultFactoryFor<HashTransformation, SHA3_512>();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2s>();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2b>();
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<Weak::MD5> >();
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<SHA1> >();
RegisterDefaultFactoryFor<MessageAuthenticationCode, HMAC<RIPEMD160> >();
@ -112,6 +115,8 @@ void RegisterFactories()
RegisterDefaultFactoryFor<MessageAuthenticationCode, CMAC<AES> >();
RegisterDefaultFactoryFor<MessageAuthenticationCode, DMAC<AES> >();
RegisterDefaultFactoryFor<MessageAuthenticationCode, CMAC<DES_EDE3> >();
RegisterDefaultFactoryFor<MessageAuthenticationCode, BLAKE2s>();
RegisterDefaultFactoryFor<MessageAuthenticationCode, BLAKE2b>();
RegisterAsymmetricCipherDefaultFactories<RSAES<OAEP<SHA1> > >("RSA/OAEP-MGF1(SHA-1)");
RegisterAsymmetricCipherDefaultFactories<DLIES<> >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)");
RegisterSignatureSchemeDefaultFactories<DSA>();
@ -171,10 +176,6 @@ void RegisterFactories()
RegisterSymmetricCipherDefaultFactories<CTR_Mode<Blowfish> >();
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SEED> >();
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SEED> >();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2s>();
RegisterDefaultFactoryFor<MessageAuthenticationCode, BLAKE2s>();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2b>();
RegisterDefaultFactoryFor<MessageAuthenticationCode, BLAKE2b>();
RegisterDefaultFactoryFor<KeyDerivationFunction, HKDF<SHA1> >();
RegisterDefaultFactoryFor<KeyDerivationFunction, HKDF<SHA256> >();
RegisterDefaultFactoryFor<KeyDerivationFunction, HKDF<SHA512> >();

View File

@ -90,6 +90,7 @@ bool ValidateAll(bool thorough)
#endif
pass=ValidateCRC32() && pass;
pass=ValidateCRC32C() && pass;
pass=ValidateAdler32() && pass;
pass=ValidateMD2() && pass;
pass=ValidateMD5() && pass;

View File

@ -115,6 +115,26 @@ bool ValidateCRC32()
return HashModuleTest(crc, testSet, sizeof(testSet)/sizeof(testSet[0]));
}
bool ValidateCRC32C()
{
HashTestTuple testSet[] =
{
HashTestTuple("", "\x00\x00\x00\x00"),
HashTestTuple("a", "\x30\x43\xd0\xc1"),
HashTestTuple("abc", "\xb7\x3f\x4b\x36"),
HashTestTuple("message digest", "\xd0\x79\xbd\x02"),
HashTestTuple("abcdefghijklmnopqrstuvwxyz", "\x25\xef\xe6\x9e"),
HashTestTuple("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\x7d\xd5\x45\xa2"),
HashTestTuple("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "\x81\x67\x7a\x47"),
HashTestTuple("123456789", "\x83\x92\x06\xe3")
};
CRC32C crc;
cout << "\nCRC-32C validation suite running...\n\n";
return HashModuleTest(crc, testSet, sizeof(testSet)/sizeof(testSet[0]));
}
bool ValidateAdler32()
{
HashTestTuple testSet[] =

View File

@ -18,6 +18,7 @@ bool TestRDSEED();
bool ValidateBaseCode();
bool ValidateCRC32();
bool ValidateCRC32C();
bool ValidateAdler32();
bool ValidateMD2();
bool ValidateMD4();