Add unit tests for CRC64.

This commit is contained in:
2021-10-05 03:12:19 +01:00
parent 8e2f7e2b55
commit 6e5ee2a705
5 changed files with 100 additions and 12 deletions

22
crc64.c
View File

@@ -36,6 +36,8 @@ AARU_EXPORT crc64_ctx* AARU_CALL crc64_init(void)
AARU_EXPORT int AARU_CALL crc64_update(crc64_ctx* ctx, const uint8_t* data, uint32_t len)
{
if(!ctx || !data) return -1;
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
if(have_clmul())
@@ -49,9 +51,14 @@ AARU_EXPORT int AARU_CALL crc64_update(crc64_ctx* ctx, const uint8_t* data, uint
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
// http://sourceforge.net/projects/slicing-by-8/
if(!ctx || !data) return -1;
crc64_slicing(&ctx->crc, data, len);
uint64_t crc = ctx->crc;
return 0;
}
AARU_EXPORT void AARU_CALL crc64_slicing(uint64_t* crc, const uint8_t* data, uint32_t len)
{
uint64_t c = *crc;
if(len > 4)
{
@@ -59,7 +66,7 @@ AARU_EXPORT int AARU_CALL crc64_update(crc64_ctx* ctx, const uint8_t* data, uint
while((uintptr_t)(data)&3)
{
crc = crc64_table[0][*data++ ^ ((crc)&0xFF)] ^ ((crc) >> 8);
c = crc64_table[0][*data++ ^ ((c)&0xFF)] ^ ((c) >> 8);
--len;
}
@@ -68,18 +75,17 @@ AARU_EXPORT int AARU_CALL crc64_update(crc64_ctx* ctx, const uint8_t* data, uint
while(data < limit)
{
const uint32_t tmp = crc ^ *(const uint32_t*)(data);
const uint32_t tmp = c ^ *(const uint32_t*)(data);
data += 4;
crc = crc64_table[3][((tmp)&0xFF)] ^ crc64_table[2][(((tmp) >> 8) & 0xFF)] ^ ((crc) >> 32) ^
c = crc64_table[3][((tmp)&0xFF)] ^ crc64_table[2][(((tmp) >> 8) & 0xFF)] ^ ((c) >> 32) ^
crc64_table[1][(((tmp) >> 16) & 0xFF)] ^ crc64_table[0][((tmp) >> 24)];
}
}
while(len-- != 0) crc = crc64_table[0][*data++ ^ ((crc)&0xFF)] ^ ((crc) >> 8);
while(len-- != 0) c = crc64_table[0][*data++ ^ ((c)&0xFF)] ^ ((c) >> 8);
ctx->crc = crc;
return 0;
*crc = c;
}
AARU_EXPORT int AARU_CALL crc64_final(crc64_ctx* ctx, uint64_t* crc)

View File

@@ -238,8 +238,9 @@ AARU_EXPORT crc64_ctx* AARU_CALL crc64_init();
AARU_EXPORT int AARU_CALL crc64_update(crc64_ctx* ctx, const uint8_t* data, uint32_t len);
AARU_EXPORT int AARU_CALL crc64_final(crc64_ctx* ctx, uint64_t* crc);
AARU_EXPORT void AARU_CALL crc64_free(crc64_ctx* ctx);
AARU_EXPORT void AARU_CALL crc64_slicing(uint64_t* crc, const uint8_t* data, uint32_t len);
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
uint64_t crc64_clmul(uint64_t crc, const uint8_t* data, size_t length);
AARU_EXPORT uint64_t AARU_CALL crc64_clmul(uint64_t crc, const uint8_t* data, long length);
#endif

View File

@@ -64,7 +64,7 @@ CLMUL static __m128i fold(__m128i in, __m128i foldConstants)
return _mm_xor_si128(_mm_clmulepi64_si128(in, foldConstants, 0x00), _mm_clmulepi64_si128(in, foldConstants, 0x11));
}
CLMUL uint64_t crc64_clmul(uint64_t crc, const uint8_t* data, size_t length)
CLMUL uint64_t crc64_clmul(uint64_t crc, const uint8_t* data, long length)
{
const uint64_t k1 = 0xe05dd497ca393ae4; // bitReflect(expMod65(128 + 64, poly, 1)) << 1;
const uint64_t k2 = 0xdabe95afc7875f40; // bitReflect(expMod65(128, poly, 1)) << 1;

View File

@@ -10,5 +10,5 @@ file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/data/random
# 'Google_Tests_run' is the target name
# 'test1.cpp tests2.cpp' are source files with tests
add_executable(tests_run adler32.cpp crc16.cpp crc32.cpp)
add_executable(tests_run adler32.cpp crc16.cpp crc32.cpp crc64.cpp)
target_link_libraries(tests_run gtest gtest_main "Aaru.Checksums.Native")

81
tests/crc64.cpp Normal file
View File

@@ -0,0 +1,81 @@
//
// Created by claunia on 5/10/21.
//
#include <cstdint>
#include "../library.h"
#include "../crc64.h"
#include "gtest/gtest.h"
#define EXPECTED_CRC64 0xbf09992cc5ede38e
static const uint8_t* buffer;
class crc64Fixture : public ::testing::Test
{
public:
crc64Fixture()
{
// initialization;
// can also be done in SetUp()
}
protected:
void SetUp()
{
FILE* file = fopen("/home/claunia/random", "rb");
buffer = (const uint8_t*)malloc(1048576);
fread((void*)buffer, 1, 1048576, file);
fclose(file);
}
void TearDown() { free((void*)buffer); }
~crc64Fixture()
{
// resources cleanup, no exceptions allowed
}
// shared user data
};
TEST_F(crc64Fixture, crc64_auto)
{
crc64_ctx* ctx = crc64_init();
uint64_t crc;
EXPECT_NE(ctx, nullptr);
crc64_update(ctx, buffer, 1048576);
crc64_final(ctx, &crc);
EXPECT_EQ(crc, EXPECTED_CRC64);
}
TEST_F(crc64Fixture, crc64_slicing)
{
uint64_t crc = CRC64_ECMA_SEED;
crc64_slicing(&crc, buffer, 1048576);
crc ^= CRC64_ECMA_SEED;
EXPECT_EQ(crc, EXPECTED_CRC64);
}
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
TEST_F(crc64Fixture, crc64_clmul)
{
if(!have_clmul()) return;
uint64_t crc = CRC64_ECMA_SEED;
crc = ~crc64_clmul(~crc, buffer, 1048576);
crc ^= CRC64_ECMA_SEED;
EXPECT_EQ(crc, EXPECTED_CRC64);
}
#endif