| | #include "../../unity/unity.h" |
| | #include <stdlib.h> |
| | #include <string.h> |
| | #include <stdint.h> |
| | #include <stdbool.h> |
| | #include <gmp.h> |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | static uuint ref_mod2_gmp(mp_limb_t a1, mp_limb_t a0, mp_limb_t d1, mp_limb_t d0) |
| | { |
| | |
| | mpz_t A, D, R; |
| | mpz_init(A); |
| | mpz_init(D); |
| | mpz_init(R); |
| |
|
| | mp_limb_t a_arr[2]; |
| | mp_limb_t d_arr[2]; |
| | a_arr[0] = a0; a_arr[1] = a1; |
| | d_arr[0] = d0; d_arr[1] = d1; |
| |
|
| | mpz_import(A, 2, -1, sizeof(mp_limb_t), 0, 0, a_arr); |
| | mpz_import(D, 2, -1, sizeof(mp_limb_t), 0, 0, d_arr); |
| |
|
| | mpz_mod(R, A, D); |
| |
|
| | mp_limb_t r_arr[2] = {0, 0}; |
| | size_t count = 0; |
| | mpz_export(r_arr, &count, -1, sizeof(mp_limb_t), 0, 0, R); |
| |
|
| | mp_limb_t r0 = (count >= 1) ? r_arr[0] : (mp_limb_t)0; |
| | mp_limb_t r1 = (count >= 2) ? r_arr[1] : (mp_limb_t)0; |
| |
|
| | mpz_clear(A); |
| | mpz_clear(D); |
| | mpz_clear(R); |
| |
|
| | return make_uuint(r1, r0); |
| | } |
| |
|
| | void setUp(void) { |
| | |
| | } |
| |
|
| | void tearDown(void) { |
| | |
| | } |
| |
|
| | |
| | void test_mod2_mod_by_base_returns_low_word(void) |
| | { |
| | mp_limb_t a1 = (((mp_limb_t)1) << (W_TYPE_SIZE - 1)) | (mp_limb_t)123u; |
| | mp_limb_t a0 = (mp_limb_t)0xDEADBEEFu; |
| | mp_limb_t d1 = (mp_limb_t)1; |
| | mp_limb_t d0 = (mp_limb_t)0; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| |
|
| | TEST_ASSERT_TRUE(hi(r) == 0); |
| | TEST_ASSERT_TRUE(lo(r) == a0); |
| | } |
| |
|
| | |
| | void test_mod2_A_less_than_D_returns_A(void) |
| | { |
| | mp_limb_t a1 = (mp_limb_t)1; |
| | mp_limb_t a0 = (mp_limb_t)12345u; |
| | mp_limb_t d1 = (mp_limb_t)2; |
| | mp_limb_t d0 = (mp_limb_t)0; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| |
|
| | TEST_ASSERT_TRUE(hi(r) == a1); |
| | TEST_ASSERT_TRUE(lo(r) == a0); |
| | } |
| |
|
| | |
| | void test_mod2_a1_zero_returns_a(void) |
| | { |
| | mp_limb_t a1 = (mp_limb_t)0; |
| | mp_limb_t a0 = (mp_limb_t)987u; |
| | mp_limb_t d1 = (mp_limb_t)1; |
| | mp_limb_t d0 = (mp_limb_t)123u; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| |
|
| | TEST_ASSERT_TRUE(hi(r) == 0); |
| | TEST_ASSERT_TRUE(lo(r) == a0); |
| | } |
| |
|
| | |
| | void test_mod2_general_against_gmp(void) |
| | { |
| | |
| | { |
| | mp_limb_t a1 = (((mp_limb_t)1) << (W_TYPE_SIZE - 1)) | (mp_limb_t)0x55u; |
| | mp_limb_t a0 = (mp_limb_t)0xA5A5A5A5u; |
| | mp_limb_t d1 = a1 >> 5; |
| | if (d1 == 0) d1 = 1; |
| | mp_limb_t d0 = (mp_limb_t)0x54321u; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| | uuint g = ref_mod2_gmp(a1, a0, d1, d0); |
| | TEST_ASSERT_TRUE(hi(r) == hi(g)); |
| | TEST_ASSERT_TRUE(lo(r) == lo(g)); |
| | } |
| |
|
| | |
| | { |
| | mp_limb_t a1 = ((((mp_limb_t)1) << (W_TYPE_SIZE - 2)) | (mp_limb_t)77u); |
| | mp_limb_t a0 = (mp_limb_t)0x12345678u; |
| | mp_limb_t d1 = a1 >> 3; |
| | if (d1 == 0) d1 = 1; |
| | mp_limb_t d0 = (mp_limb_t)0x9ABCDEFFu; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| | uuint g = ref_mod2_gmp(a1, a0, d1, d0); |
| | TEST_ASSERT_TRUE(hi(r) == hi(g)); |
| | TEST_ASSERT_TRUE(lo(r) == lo(g)); |
| | } |
| |
|
| | |
| | { |
| | mp_limb_t a1 = (((mp_limb_t)1) << (W_TYPE_SIZE - 1)); |
| | mp_limb_t a0 = (mp_limb_t)0xCAFEBABEu; |
| | mp_limb_t d1 = a1 >> 7; |
| | if (d1 == 0) d1 = 1; |
| | mp_limb_t d0 = (mp_limb_t)0; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| | uuint g = ref_mod2_gmp(a1, a0, d1, d0); |
| | TEST_ASSERT_TRUE(hi(r) == hi(g)); |
| | TEST_ASSERT_TRUE(lo(r) == lo(g)); |
| | } |
| |
|
| | |
| | { |
| | mp_limb_t a1 = (((mp_limb_t)1) << (W_TYPE_SIZE - 1)) | (mp_limb_t)0xF0u; |
| | mp_limb_t a0 = (mp_limb_t)0x0BADF00Du; |
| | mp_limb_t d1 = (mp_limb_t)1; |
| | mp_limb_t d0 = (mp_limb_t)0x11111111u; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| | uuint g = ref_mod2_gmp(a1, a0, d1, d0); |
| | TEST_ASSERT_TRUE(hi(r) == hi(g)); |
| | TEST_ASSERT_TRUE(lo(r) == lo(g)); |
| | } |
| |
|
| | |
| | { |
| | mp_limb_t a1 = (mp_limb_t)(~(mp_limb_t)0); |
| | mp_limb_t a0 = (mp_limb_t)0xFFFFFFFFu; |
| | mp_limb_t d1 = a1 >> 4; |
| | if (d1 == 0) d1 = 1; |
| | mp_limb_t d0 = (mp_limb_t)0xFEEDFACEu; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| | uuint g = ref_mod2_gmp(a1, a0, d1, d0); |
| | TEST_ASSERT_TRUE(hi(r) == hi(g)); |
| | TEST_ASSERT_TRUE(lo(r) == lo(g)); |
| | } |
| | } |
| |
|
| | |
| | void test_mod2_divisible_case_zero_remainder(void) |
| | { |
| | mp_limb_t d1 = (mp_limb_t)1; |
| | mp_limb_t d0 = (mp_limb_t)0x11111111u; |
| |
|
| | |
| | mp_limb_t a0 = d0 << 1; |
| | mp_limb_t carry = (d0 >> (W_TYPE_SIZE - 1)); |
| | mp_limb_t a1 = (d1 << 1) + carry; |
| |
|
| | uuint r = mod2(a1, a0, d1, d0); |
| |
|
| | TEST_ASSERT_TRUE(hi(r) == 0); |
| | TEST_ASSERT_TRUE(lo(r) == 0); |
| | } |
| |
|
| | int main(void) |
| | { |
| | UNITY_BEGIN(); |
| | RUN_TEST(test_mod2_mod_by_base_returns_low_word); |
| | RUN_TEST(test_mod2_A_less_than_D_returns_A); |
| | RUN_TEST(test_mod2_a1_zero_returns_a); |
| | RUN_TEST(test_mod2_general_against_gmp); |
| | RUN_TEST(test_mod2_divisible_case_zero_remainder); |
| | return UNITY_END(); |
| | } |