| #include "unity/unity.h" |
| #include "zlib.h" |
| #include <stdint.h> |
| #include <stdlib.h> |
|
|
| |
| extern z_crc_t test_x2nmodp(z_off64_t n, unsigned k); |
|
|
| void setUp(void) { |
| |
| const z_crc_t *tbl = get_crc_table(); |
| TEST_ASSERT_NOT_NULL(tbl); |
| } |
|
|
| void tearDown(void) { |
| |
| } |
|
|
| |
| |
| static uint32_t op_mul(uint32_t opA, uint32_t opB) { |
| uLong prod = crc32_combine_op((uLong)opB, (uLong)0, (uLong)opA); |
| return (uint32_t)prod; |
| } |
|
|
| void test_x2nmodp_identity_and_small_powers(void) { |
| |
| uint32_t id0 = (uint32_t)test_x2nmodp((z_off64_t)0, 0); |
| uint32_t id17 = (uint32_t)test_x2nmodp((z_off64_t)0, 17); |
| uint32_t id31 = (uint32_t)test_x2nmodp((z_off64_t)0, 31); |
| uint32_t id63 = (uint32_t)test_x2nmodp((z_off64_t)0, 63); |
| TEST_ASSERT_EQUAL_HEX32(0x80000000u, id0); |
| TEST_ASSERT_EQUAL_HEX32(0x80000000u, id17); |
| TEST_ASSERT_EQUAL_HEX32(0x80000000u, id31); |
| TEST_ASSERT_EQUAL_HEX32(0x80000000u, id63); |
|
|
| |
| uint32_t x1 = (uint32_t)test_x2nmodp((z_off64_t)1, 0); |
| uint32_t x2 = (uint32_t)test_x2nmodp((z_off64_t)1, 1); |
| uint32_t x3 = (uint32_t)test_x2nmodp((z_off64_t)1, 2); |
| uint32_t x2_direct = (uint32_t)test_x2nmodp((z_off64_t)2, 0); |
| uint32_t x3_direct = (uint32_t)test_x2nmodp((z_off64_t)4, 0); |
| TEST_ASSERT_EQUAL_HEX32(0x40000000u, x1); |
| TEST_ASSERT_EQUAL_HEX32(0x20000000u, x2); |
| TEST_ASSERT_EQUAL_HEX32(0x10000000u, x3); |
| TEST_ASSERT_EQUAL_HEX32(0x20000000u, x2_direct); |
| TEST_ASSERT_EQUAL_HEX32(0x10000000u, x3_direct); |
| } |
|
|
| void test_x2nmodp_leftshift_equivalence(void) { |
| |
| z_off64_t n = (z_off64_t)0x1234; |
| unsigned k = 5; |
| z_off64_t n_shift = n << k; |
| uint32_t a = (uint32_t)test_x2nmodp(n, k); |
| uint32_t b = (uint32_t)test_x2nmodp(n_shift, 0); |
| TEST_ASSERT_EQUAL_HEX32(b, a); |
|
|
| n = 7; |
| k = 3; |
| n_shift = n << k; |
| a = (uint32_t)test_x2nmodp(n, k); |
| b = (uint32_t)test_x2nmodp(n_shift, 0); |
| TEST_ASSERT_EQUAL_HEX32(b, a); |
| } |
|
|
| void test_x2nmodp_k_wraparound_32(void) { |
| |
| z_off64_t n = 7; |
| uint32_t a = (uint32_t)test_x2nmodp(n, 3); |
| uint32_t b = (uint32_t)test_x2nmodp(n, 3 + 32); |
| uint32_t c = (uint32_t)test_x2nmodp(n, 3 + 64); |
| TEST_ASSERT_EQUAL_HEX32(a, b); |
| TEST_ASSERT_EQUAL_HEX32(a, c); |
|
|
| n = 12345; |
| a = (uint32_t)test_x2nmodp(n, 0); |
| b = (uint32_t)test_x2nmodp(n, 32); |
| TEST_ASSERT_EQUAL_HEX32(a, b); |
| } |
|
|
| void test_x2nmodp_matches_combine_gen64(void) { |
| |
| z_off64_t cases[] = { |
| 0, 1, 2, 3, 7, 31, 32, 33, 123, 1000000, |
| (z_off64_t)1234567890123LL |
| }; |
| size_t i; |
| for (i = 0; i < sizeof(cases)/sizeof(cases[0]); i++) { |
| z_off64_t n = cases[i]; |
| uint32_t a = (uint32_t)test_x2nmodp(n, 3); |
| uint32_t b = (uint32_t)crc32_combine_gen64(n); |
| TEST_ASSERT_EQUAL_HEX32(b, a); |
| } |
|
|
| |
| z_off64_t large_n = (z_off64_t)0x7fffffffffffffffLL; |
| uint32_t a = (uint32_t)test_x2nmodp(large_n, 3); |
| uint32_t b = (uint32_t)crc32_combine_gen64(large_n); |
| TEST_ASSERT_EQUAL_HEX32(b, a); |
| } |
|
|
| void test_x2nmodp_additivity_via_multiplication(void) { |
| |
| unsigned k = 7; |
| z_off64_t a_len = 5; |
| z_off64_t b_len = 12; |
|
|
| uint32_t op_a = (uint32_t)test_x2nmodp(a_len, k); |
| uint32_t op_b = (uint32_t)test_x2nmodp(b_len, k); |
| uint32_t op_ab = (uint32_t)test_x2nmodp(a_len + b_len, k); |
|
|
| uint32_t prod = op_mul(op_a, op_b); |
| TEST_ASSERT_EQUAL_HEX32(op_ab, prod); |
|
|
| |
| z_off64_t c_len = 9; |
| uint32_t op_c = (uint32_t)test_x2nmodp(c_len, k); |
| uint32_t op_sum = (uint32_t)test_x2nmodp(a_len + b_len + c_len, k); |
| uint32_t prod2 = op_mul(prod, op_c); |
| TEST_ASSERT_EQUAL_HEX32(op_sum, prod2); |
| } |
|
|
| void test_x2nmodp_construct_from_bits(void) { |
| |
| z_off64_t n = 13; |
| unsigned k = 7; |
|
|
| uint32_t expected = (uint32_t)test_x2nmodp(n, k); |
|
|
| uint32_t accum = (uint32_t)test_x2nmodp(0, k); |
| unsigned i = 0; |
| z_off64_t tmp = n; |
| while (tmp) { |
| if (tmp & 1) { |
| uint32_t term = (uint32_t)test_x2nmodp(1, k + i); |
| accum = op_mul(accum, term); |
| } |
| tmp >>= 1; |
| i++; |
| } |
| TEST_ASSERT_EQUAL_HEX32(expected, accum); |
| } |
|
|
| int main(void) { |
| UNITY_BEGIN(); |
| RUN_TEST(test_x2nmodp_identity_and_small_powers); |
| RUN_TEST(test_x2nmodp_leftshift_equivalence); |
| RUN_TEST(test_x2nmodp_k_wraparound_32); |
| RUN_TEST(test_x2nmodp_matches_combine_gen64); |
| RUN_TEST(test_x2nmodp_additivity_via_multiplication); |
| RUN_TEST(test_x2nmodp_construct_from_bits); |
| return UNITY_END(); |
| } |