#include #include #include static int fields(void) { bh_bigint_t bint; bh_bigint_init(&bint); /* Ensure that methods reflect big integer fields */ bint.error = 0; bint.type = 0; bh_unit_assert(bint.error == bh_bigint_is_error(&bint)); bh_unit_assert((bint.type < 0) == bh_bigint_is_negative(&bint)); bh_unit_assert((bint.type == 0) == bh_bigint_is_zero(&bint)); bint.error = 0; bint.type = 1; bh_unit_assert(bint.error == bh_bigint_is_error(&bint)); bh_unit_assert((bint.type < 0) == bh_bigint_is_negative(&bint)); bh_unit_assert((bint.type == 0) == bh_bigint_is_zero(&bint)); bint.type = -1; bh_unit_assert(bint.error == bh_bigint_is_error(&bint)); bh_unit_assert((bint.type < 0) == bh_bigint_is_negative(&bint)); bh_unit_assert((bint.type == 0) == bh_bigint_is_zero(&bint)); bint.error = 1; bh_unit_assert(bint.error == bh_bigint_is_error(&bint)); bh_bigint_destroy(&bint); return 0; } static int round_trip(void) { bh_bigint_t *data[10]; size_t i; for (i = 0; i < 10; i++) { data[i] = bh_bigint_new(); bh_unit_assert(data[i] != NULL); } bh_unit_assert(bh_bigint_set_int(data[0], -12345) == BH_OK); bh_unit_assert(bh_bigint_get_int(data[0]) == -12345); bh_unit_assert(bh_bigint_set_int8(data[1], -120) == BH_OK); bh_unit_assert(bh_bigint_get_int8(data[1]) == -120); bh_unit_assert(bh_bigint_set_int16(data[2], -12345) == BH_OK); bh_unit_assert(bh_bigint_get_int16(data[2]) == -12345); bh_unit_assert(bh_bigint_set_int32(data[3], -12345678l) == BH_OK); bh_unit_assert(bh_bigint_get_int32(data[3]) == -12345678l); bh_unit_assert(bh_bigint_set_int64(data[4], -123456789012345ll) == BH_OK); bh_unit_assert(bh_bigint_get_int64(data[4]) == -123456789012345ll); bh_unit_assert(bh_bigint_set_uint(data[5], 12345) == BH_OK); bh_unit_assert(bh_bigint_get_uint(data[5]) == 12345); bh_unit_assert(bh_bigint_set_uint8(data[6], 230) == BH_OK); bh_unit_assert(bh_bigint_get_uint8(data[6]) == 230); bh_unit_assert(bh_bigint_set_uint16(data[7], 40000) == BH_OK); bh_unit_assert(bh_bigint_get_uint16(data[7]) == 40000); bh_unit_assert(bh_bigint_set_uint32(data[8], 12345678ul) == BH_OK); bh_unit_assert(bh_bigint_get_uint32(data[8]) == 12345678ul); bh_unit_assert(bh_bigint_set_uint64(data[9], 123456789012345ull) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(data[9]) == 123456789012345ull); for (i = 0; i < 10; i++) bh_bigint_free(data[i]); return 0; } static int add_sub(void) { const bh_uint64_t ta = 0xA3B1DBC158176B96ull, tb = 0x2748D1622F3E90A2ull; bh_bigint_t *a, *b, *c; /* Allocate new big integers */ a = bh_bigint_new(); b = bh_bigint_new(); c = bh_bigint_new(); bh_unit_assert(a != NULL); bh_unit_assert(b != NULL); bh_unit_assert(c != NULL); /* Test correct result sign */ bh_unit_assert(bh_bigint_set_int(a, 3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 5) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 8); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -2); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 5) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 2); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -8); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_set_int(a, 3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -5) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -2); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 8); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -5) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -8); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 2); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); /* Edge cases for correct sign */ bh_unit_assert(bh_bigint_set_int(a, 3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 3) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 6); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 3) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -6); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_set_int(a, 3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -3) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 6); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -3) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -3) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -6); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_is_error(c) == 0); /* Set 'multi-digit' integers */ bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK); bh_unit_assert(bh_bigint_set_uint64(b, tb) == BH_OK); /* Test addition and subtraction */ bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta + tb)); bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta - tb)); /* Overwrites */ bh_unit_assert(bh_bigint_set(c, a) == BH_OK); bh_unit_assert(bh_bigint_add(c, c, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta + tb)); bh_unit_assert(bh_bigint_set(c, b) == BH_OK); bh_unit_assert(bh_bigint_add(c, a, c) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta + tb)); bh_unit_assert(bh_bigint_set(c, a) == BH_OK); bh_unit_assert(bh_bigint_sub(c, c, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta - tb)); bh_unit_assert(bh_bigint_set(c, b) == BH_OK); bh_unit_assert(bh_bigint_sub(c, a, c) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta - tb)); /* Check for error handling */ a->error = 0; b->error = 0; c->error = 1; bh_unit_assert(bh_bigint_add(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); c->error = 1; bh_unit_assert(bh_bigint_sub(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); a->error = 1; b->error = 0; c->error = 0; bh_unit_assert(bh_bigint_add(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_sub(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); a->error = 0; b->error = 1; c->error = 0; bh_unit_assert(bh_bigint_add(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_sub(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); a->error = 1; b->error = 1; c->error = 0; bh_unit_assert(bh_bigint_add(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_sub(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); /* Free big integers */ bh_bigint_free(a); bh_bigint_free(b); bh_bigint_free(c); return 0; } static int multiplication(void) { bh_bigint_t *a, *b, *c, *d; int i; /* Allocate new big integers */ a = bh_bigint_new(); b = bh_bigint_new(); c = bh_bigint_new(); d = bh_bigint_new(); bh_unit_assert(a != NULL); bh_unit_assert(b != NULL); bh_unit_assert(c != NULL); bh_unit_assert(d != NULL); /* Set big integers to arbitrary number */ bh_unit_assert(bh_bigint_set_int(a, 1234567) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 1234567) == BH_OK); /* Reference multiplication by addition */ bh_unit_assert(bh_bigint_reserve(c, a->size + b->size + 1) == BH_OK); bh_unit_assert(bh_bigint_set(c, a) == BH_OK); for (i = 1; i < 1234567; i++) bh_unit_assert(bh_bigint_add(c, c, a) == BH_OK); /* Multiplication and compare for equality */ bh_unit_assert(bh_bigint_mul(d, a, b) == BH_OK); bh_unit_assert(bh_bigint_equal(c, d) == 0); /* Check signs */ bh_unit_assert(bh_bigint_set_int(a, 2) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 2) == BH_OK); bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 4); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_set_int(a, 2) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -2) == BH_OK); bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -4); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -2) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 2) == BH_OK); bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -4); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -2) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -2) == BH_OK); bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 4); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); /* Check multiplication by zero */ bh_unit_assert(bh_bigint_set_int(a, 2) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 0) == BH_OK); bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_set_int(a, 0) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 2) == BH_OK); bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_set_int(a, 0) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 0) == BH_OK); bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); /* Overwrites */ bh_unit_assert(bh_bigint_set_int(a, 1234) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 4321) == BH_OK); bh_unit_assert(bh_bigint_mul(a, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(a) == 1234 * 4321); bh_unit_assert(bh_bigint_set_int(a, 1234) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 4321) == BH_OK); bh_unit_assert(bh_bigint_mul(b, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(b) == 1234 * 4321); bh_unit_assert(bh_bigint_set_int(a, 1234) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 4321) == BH_OK); bh_unit_assert(bh_bigint_mul(a, a, a) == BH_OK); bh_unit_assert(bh_bigint_get_int(a) == 1234 * 1234); /* Check digit multiplication */ bh_unit_assert(bh_bigint_set_int(a, 1234567) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, 12345) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == 15240729615ull); /* Check digit multiplication by zero */ bh_unit_assert(bh_bigint_set_int(a, 2) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, 0) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_set_int(a, 0) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, 2) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_set_int(a, 0) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, 0) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); /* Check digit multiplication signs */ bh_unit_assert(bh_bigint_set_int(a, 2) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, 2) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 4); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_set_int(a, 2) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, -2) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -4); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -2) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, 2) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -4); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_set_int(a, -2) == BH_OK); bh_unit_assert(bh_bigint_mul_digit(c, a, -2) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 4); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); /* Check for error handling */ a->error = 0; b->error = 0; c->error = 1; bh_unit_assert(bh_bigint_mul(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); a->error = 1; b->error = 0; c->error = 0; bh_unit_assert(bh_bigint_mul(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); a->error = 0; b->error = 1; c->error = 0; bh_unit_assert(bh_bigint_mul(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); a->error = 1; b->error = 1; c->error = 0; bh_unit_assert(bh_bigint_mul(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); /* Check for digit multiplication error handling */ a->error = 0; c->error = 1; bh_unit_assert(bh_bigint_mul_digit(c, a, 10) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); a->error = 1; c->error = 0; bh_unit_assert(bh_bigint_mul_digit(c, a, 10) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); bh_bigint_free(a); bh_bigint_free(b); bh_bigint_free(c); bh_bigint_free(d); return 0; } static int logic(void) { const bh_uint64_t ta = 0xA3B1DBC158176B96ull, tb = 0x2748D1622F3E90A2ull; bh_bigint_t *a, *b, *c; /* Allocate big integers */ a = bh_bigint_new(); b = bh_bigint_new(); c = bh_bigint_new(); bh_unit_assert(a != NULL); bh_unit_assert(b != NULL); bh_unit_assert(c != NULL); /* Copy from reference integers */ bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK); bh_unit_assert(bh_bigint_set_uint64(b, tb) == BH_OK); /* Logic OR */ bh_unit_assert(bh_bigint_or(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta | tb)); bh_unit_assert(bh_bigint_is_negative(c) == 0); /* Logic AND */ bh_unit_assert(bh_bigint_and(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta & tb)); bh_unit_assert(bh_bigint_is_negative(c) == 0); /* Logic XOR */ bh_unit_assert(bh_bigint_xor(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (ta ^ tb)); bh_unit_assert(bh_bigint_is_negative(c) == 0); /* Operations with zero */ bh_unit_assert(bh_bigint_clear(b) == BH_OK); bh_unit_assert(bh_bigint_and(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); bh_unit_assert(bh_bigint_or(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == ta); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_xor(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == ta); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); /* Copy from reference integers */ bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK); bh_unit_assert(bh_bigint_set_uint64(b, tb) == BH_OK); /* Logic shift left */ bh_unit_assert(bh_bigint_lsh(c, b, 1) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (tb << 1)); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); /* Logic shift right */ bh_unit_assert(bh_bigint_rsh(c, b, 1) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == (tb >> 1)); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); /* Zero bit shifts */ bh_unit_assert(bh_bigint_lsh(c, b, 0) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == tb); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_rsh(c, b, 0) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == tb); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); /* Full width shift */ bh_unit_assert(bh_bigint_rsh(c, b, 64) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == 0); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) != 0); /* Large shifts */ bh_unit_assert(bh_bigint_rsh(c, a, 60) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == 0xA); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); bh_unit_assert(bh_bigint_lsh(c, a, 100) == BH_OK); bh_unit_assert(bh_bigint_rsh(c, c, 100) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == ta); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_zero(c) == 0); /* Check for error handling */ a->error = 0; b->error = 0; c->error = 1; bh_unit_assert(bh_bigint_or(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); c->error = 1; bh_unit_assert(bh_bigint_and(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); c->error = 1; bh_unit_assert(bh_bigint_xor(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); c->error = 1; bh_unit_assert(bh_bigint_lsh(c, a, 1) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); c->error = 1; bh_unit_assert(bh_bigint_rsh(c, a, 1) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); a->error = 1; b->error = 0; c->error = 0; bh_unit_assert(bh_bigint_or(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_and(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_xor(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_lsh(c, a, 1) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_rsh(c, a, 1) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); a->error = 0; b->error = 1; c->error = 0; bh_unit_assert(bh_bigint_or(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_and(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_xor(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); a->error = 1; b->error = 1; c->error = 0; bh_unit_assert(bh_bigint_or(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_and(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); c->error = 0; bh_unit_assert(bh_bigint_xor(c, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); /* Free big integers */ bh_bigint_free(a); bh_bigint_free(b); bh_bigint_free(c); return 0; } static int division(void) { const bh_uint64_t ta = 0x41F915031348A134ull, tb = 0x434115F6ull, tc = 0x153F14ABull; const bh_uint64_t td = 0xD0D561E41F7EA081ull, te = 0x0459E1CDull; bh_bigint_t *a, *b, *c, *d; /* Allocate big integers */ a = bh_bigint_new(); b = bh_bigint_new(); c = bh_bigint_new(); d = bh_bigint_new(); bh_unit_assert(a != NULL); bh_unit_assert(b != NULL); bh_unit_assert(c != NULL); bh_unit_assert(d != NULL); /* Set integers to test values */ bh_unit_assert(bh_bigint_set_uint64(a, ta) == BH_OK); bh_unit_assert(bh_bigint_set_uint64(b, tb) == BH_OK); bh_unit_assert(bh_bigint_mul(a, a, b) == BH_OK); bh_unit_assert(bh_bigint_set_uint64(b, tc) == BH_OK); /* Divide and check result for div&mod operation */ bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == td); bh_unit_assert(bh_bigint_get_uint64(d) == te); /* Check for division */ bh_unit_assert(bh_bigint_div(c, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(c) == td); /* Check for modulos */ bh_unit_assert(bh_bigint_mod(d, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_uint64(d) == te); /* Check division with zero */ bh_unit_assert(bh_bigint_set_int(a, 0) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 50) == BH_OK); bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 0); bh_unit_assert(bh_bigint_get_int(d) == 0); bh_unit_assert(bh_bigint_set_int(a, 50) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 0) == BH_OK); bh_unit_assert(bh_bigint_divmod(c, d, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); bh_unit_assert(bh_bigint_is_error(d) != 0); /* Check signs */ bh_unit_assert(bh_bigint_set_int(a, 1773) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 50) == BH_OK); bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 35); bh_unit_assert(bh_bigint_get_int(d) == 23); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_negative(d) == 0); bh_unit_assert(bh_bigint_mul(c, c, b) == BH_OK); bh_unit_assert(bh_bigint_add(c, c, d) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 1773); bh_unit_assert(bh_bigint_set_int(a, 1773) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -50) == BH_OK); bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -35); bh_unit_assert(bh_bigint_get_int(d) == 23); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_negative(d) == 0); bh_unit_assert(bh_bigint_mul(c, c, b) == BH_OK); bh_unit_assert(bh_bigint_add(c, c, d) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 1773); bh_unit_assert(bh_bigint_set_int(a, -1773) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 50) == BH_OK); bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -35); bh_unit_assert(bh_bigint_get_int(d) == -23); bh_unit_assert(bh_bigint_is_negative(c) != 0); bh_unit_assert(bh_bigint_is_negative(d) != 0); bh_unit_assert(bh_bigint_mul(c, c, b) == BH_OK); bh_unit_assert(bh_bigint_add(c, c, d) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -1773); bh_unit_assert(bh_bigint_set_int(a, -1773) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, -50) == BH_OK); bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == 35); bh_unit_assert(bh_bigint_get_int(d) == -23); bh_unit_assert(bh_bigint_is_negative(c) == 0); bh_unit_assert(bh_bigint_is_negative(d) != 0); bh_unit_assert(bh_bigint_mul(c, c, b) == BH_OK); bh_unit_assert(bh_bigint_add(c, c, d) == BH_OK); bh_unit_assert(bh_bigint_get_int(c) == -1773); /* Check for error handling */ a->error = 0; b->error = 0; c->error = 1; d->error = 1; bh_unit_assert(bh_bigint_divmod(c, d, a, b) == BH_OK); bh_unit_assert(bh_bigint_is_error(c) == 0); bh_unit_assert(bh_bigint_is_error(d) == 0); a->error = 1; b->error = 0; c->error = 0; d->error = 0; bh_unit_assert(bh_bigint_divmod(c, d, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); bh_unit_assert(bh_bigint_is_error(d) != 0); a->error = 0; b->error = 1; c->error = 0; d->error = 0; bh_unit_assert(bh_bigint_divmod(c, d, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); bh_unit_assert(bh_bigint_is_error(d) != 0); a->error = 1; b->error = 1; c->error = 0; d->error = 0; bh_unit_assert(bh_bigint_divmod(c, d, a, b) != BH_OK); bh_unit_assert(bh_bigint_is_error(c) != 0); bh_unit_assert(bh_bigint_is_error(d) != 0); /* Deallocate big integers */ bh_bigint_free(a); bh_bigint_free(b); bh_bigint_free(c); bh_bigint_free(d); return 0; } static int power(void) { bh_bigint_t *a, *b, *c, *d, *e; /* Allocate big integers */ a = bh_bigint_new(); b = bh_bigint_new(); c = bh_bigint_new(); d = bh_bigint_new(); e = bh_bigint_new(); bh_unit_assert(a != NULL); bh_unit_assert(b != NULL); bh_unit_assert(c != NULL); bh_unit_assert(d != NULL); bh_unit_assert(e != NULL); /* Check sign */ bh_unit_assert(bh_bigint_set_int(a, 137) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 3) == BH_OK); bh_unit_assert(bh_bigint_set_int64(c, 10000000ll) == BH_OK); bh_unit_assert(bh_bigint_pow(d, a, 3) == BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK); bh_unit_assert(bh_bigint_equal(d, e) == 0); bh_unit_assert(bh_bigint_get_int64(e) == 2571353ll); bh_unit_assert(bh_bigint_set_int(a, -137) == BH_OK); bh_unit_assert(bh_bigint_pow(d, a, 3) == BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK); bh_unit_assert(bh_bigint_equal(d, e) == 0); bh_unit_assert(bh_bigint_get_int64(e) == -2571353ll); /* Power of zero */ bh_unit_assert(bh_bigint_set_int(a, 137) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 0) == BH_OK); bh_unit_assert(bh_bigint_set_int64(c, 10000000ll) == BH_OK); bh_unit_assert(bh_bigint_pow(d, a, 0) == BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK); bh_unit_assert(bh_bigint_equal(d, e) == 0); bh_unit_assert(bh_bigint_get_int64(e) == 1); /* Zero in some power */ bh_unit_assert(bh_bigint_set_int(a, 0) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 50) == BH_OK); bh_unit_assert(bh_bigint_set_int64(c, 10000000ll) == BH_OK); bh_unit_assert(bh_bigint_pow(d, a, 50) == BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK); bh_unit_assert(bh_bigint_equal(d, e) == 0); bh_unit_assert(bh_bigint_get_int64(e) == 0); /* Zero in power of zero */ bh_unit_assert(bh_bigint_set_int(a, 0) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 0) == BH_OK); bh_unit_assert(bh_bigint_set_int64(c, 10000000ll) == BH_OK); bh_unit_assert(bh_bigint_pow(d, a, 0) == BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK); bh_unit_assert(bh_bigint_equal(d, e) == 0); bh_unit_assert(bh_bigint_get_int64(e) == 1); /* Error handling */ a->error = 0; b->error = 0; c->error = 0; d->error = 1; e->error = 1; bh_unit_assert(bh_bigint_pow(d, a, 3) == BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK); bh_unit_assert(bh_bigint_is_error(d) == 0); bh_unit_assert(bh_bigint_is_error(e) == 0); a->error = 1; b->error = 0; c->error = 0; d->error = 0; e->error = 0; bh_unit_assert(bh_bigint_pow(d, a, 3) != BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) != BH_OK); bh_unit_assert(bh_bigint_is_error(d) != 0); bh_unit_assert(bh_bigint_is_error(e) != 0); a->error = 0; b->error = 1; c->error = 0; e->error = 0; bh_unit_assert(bh_bigint_powm(e, a, b, c) != BH_OK); bh_unit_assert(bh_bigint_is_error(e) != 0); a->error = 1; b->error = 1; c->error = 0; e->error = 0; bh_unit_assert(bh_bigint_powm(e, a, b, c) != BH_OK); bh_unit_assert(bh_bigint_is_error(e) != 0); a->error = 0; b->error = 0; c->error = 1; e->error = 0; bh_unit_assert(bh_bigint_powm(e, a, b, c) != BH_OK); bh_unit_assert(bh_bigint_is_error(e) != 0); a->error = 1; b->error = 0; c->error = 1; e->error = 0; bh_unit_assert(bh_bigint_powm(e, a, b, c) != BH_OK); bh_unit_assert(bh_bigint_is_error(e) != 0); a->error = 0; b->error = 1; c->error = 1; e->error = 0; bh_unit_assert(bh_bigint_powm(e, a, b, c) != BH_OK); bh_unit_assert(bh_bigint_is_error(e) != 0); a->error = 1; b->error = 1; c->error = 1; e->error = 0; bh_unit_assert(bh_bigint_powm(e, a, b, c) != BH_OK); bh_unit_assert(bh_bigint_is_error(e) != 0); /* Large powers */ /* TODO: Replace this with some better test */ bh_unit_assert(bh_bigint_set_int(a, 137) == BH_OK); bh_unit_assert(bh_bigint_set_int(b, 2048) == BH_OK); bh_unit_assert(bh_bigint_set_int(c, 100) == BH_OK); bh_unit_assert(bh_bigint_pow(d, a, 2048) == BH_OK); bh_unit_assert(bh_bigint_mod(d, d, c) == BH_OK); bh_unit_assert(bh_bigint_powm(e, a, b, c) == BH_OK); bh_unit_assert(bh_bigint_equal(d, e) == 0); bh_unit_assert(bh_bigint_get_int(d) == 21); /* Deallocate big integers */ bh_bigint_free(a); bh_bigint_free(b); bh_bigint_free(c); bh_bigint_free(d); bh_bigint_free(e); return 0; } int main(int argc, char **argv) { (void)argc; (void)argv; /* Add unit tests */ bh_unit_add("fields", fields); bh_unit_add("round_trip", round_trip); bh_unit_add("add_sub", add_sub); bh_unit_add("multiplication", multiplication); bh_unit_add("logic", logic); bh_unit_add("division", division); bh_unit_add("power", power); return bh_unit_run(); }