zlib / tests /tests_crc32_multmodp.c
AryaWu's picture
Upload folder using huggingface_hub
e996a55 verified
#include "unity/unity.h"
#include "zlib.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
/* The wrapper provided in the module for the local function. */
extern unsigned long test_multmodp(unsigned long a, unsigned long b);
static uint32_t ref_multmodp(uint32_t a, uint32_t b) {
/* Reference polynomial multiplication in GF(2) modulo reflected CRC-32 POLY. */
const uint32_t POLY = 0xEDB88320u;
uint32_t p = 0;
while (a) {
if (a & 1u) {
p ^= b;
}
a >>= 1;
if (b & 1u) {
b = (b >> 1) ^ POLY;
} else {
b >>= 1;
}
}
return p;
}
void setUp(void) {
/* Setup code here, or leave empty */
}
void tearDown(void) {
/* Cleanup code here, or leave empty */
}
static uint32_t call_ut(uint32_t a, uint32_t b) {
/* Helper to call the unit under test and cast to 32-bit for assertions. */
unsigned long r = test_multmodp((unsigned long)a, (unsigned long)b);
return (uint32_t)r;
}
void test_multmodp_identity_right(void) {
uint32_t a = 0xCAFEBABEu; /* non-zero */
uint32_t b = 1u;
uint32_t got = call_ut(a, b);
TEST_ASSERT_EQUAL_HEX32(a, got);
}
void test_multmodp_identity_left(void) {
uint32_t a = 1u; /* non-zero */
uint32_t b = 0xAABBCCDDu;
uint32_t got = call_ut(a, b);
TEST_ASSERT_EQUAL_HEX32(b, got);
}
void test_multmodp_zero_b(void) {
uint32_t a = 0x12345678u; /* non-zero */
uint32_t b = 0u;
uint32_t got = call_ut(a, b);
TEST_ASSERT_EQUAL_HEX32(0u, got);
}
void test_multmodp_commutative_fixed(void) {
uint32_t a = 0x13579BDFu; /* non-zero */
uint32_t b = 0x2468ACE1u; /* non-zero */
uint32_t ab = call_ut(a, b);
uint32_t ba = call_ut(b, a);
TEST_ASSERT_EQUAL_HEX32(ab, ba);
/* Also verify against reference for extra certainty. */
uint32_t ref = ref_multmodp(a, b);
TEST_ASSERT_EQUAL_HEX32(ref, ab);
}
void test_multmodp_distributive_over_xor(void) {
uint32_t a = 0xDEADBEEFu; /* non-zero */
uint32_t b = 0x0F0F0F0Fu;
uint32_t c = 0x33333333u;
uint32_t left = call_ut(a, b ^ c);
uint32_t right = call_ut(a, b) ^ call_ut(a, c);
TEST_ASSERT_EQUAL_HEX32(right, left);
}
void test_multmodp_single_bit_a_positions(void) {
uint32_t b = 0x89ABCDEFu;
uint8_t positions[] = {0, 1, 7, 15, 31};
for (size_t i = 0; i < sizeof(positions)/sizeof(positions[0]); i++) {
uint32_t a = 1u << positions[i];
uint32_t got = call_ut(a, b);
uint32_t exp = ref_multmodp(a, b);
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
}
void test_multmodp_max_values(void) {
uint32_t a = 0xFFFFFFFFu; /* non-zero */
uint32_t b = 0xFFFFFFFFu;
uint32_t got = call_ut(a, b);
uint32_t exp = ref_multmodp(a, b);
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
static uint32_t rand32(void) {
/* Compose a 32-bit value from multiple rand() calls to avoid low-bit bias. */
uint32_t r = 0;
r ^= ((uint32_t)rand() & 0x3FFu) << 22;
r ^= ((uint32_t)rand() & 0x7FFFu) << 7;
r ^= ((uint32_t)rand() & 0x7Fu);
return r;
}
void test_multmodp_matches_reference_random(void) {
srand(12345);
for (int i = 0; i < 100; i++) {
uint32_t a = rand32() | 1u; /* ensure non-zero to avoid undefined behavior */
uint32_t b = rand32();
uint32_t got = call_ut(a, b);
uint32_t exp = ref_multmodp(a, b);
TEST_ASSERT_EQUAL_HEX32(exp, got);
}
}
int main(void) {
UNITY_BEGIN();
RUN_TEST(test_multmodp_identity_right);
RUN_TEST(test_multmodp_identity_left);
RUN_TEST(test_multmodp_zero_b);
RUN_TEST(test_multmodp_commutative_fixed);
RUN_TEST(test_multmodp_distributive_over_xor);
RUN_TEST(test_multmodp_single_bit_a_positions);
RUN_TEST(test_multmodp_max_values);
RUN_TEST(test_multmodp_matches_reference_random);
return UNITY_END();
}