michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include "mpi.h" michael@0: #include "mpprime.h" michael@0: #include michael@0: #include michael@0: michael@0: #define MAX_PREC (4096 / MP_DIGIT_BIT) michael@0: michael@0: mp_err identity_test(void) michael@0: { michael@0: mp_size preca, precb; michael@0: mp_err res; michael@0: mp_int a, b; michael@0: mp_int t1, t2, t3, t4, t5; michael@0: michael@0: preca = (rand() % MAX_PREC) + 1; michael@0: precb = (rand() % MAX_PREC) + 1; michael@0: michael@0: MP_DIGITS(&a) = 0; michael@0: MP_DIGITS(&b) = 0; michael@0: MP_DIGITS(&t1) = 0; michael@0: MP_DIGITS(&t2) = 0; michael@0: MP_DIGITS(&t3) = 0; michael@0: MP_DIGITS(&t4) = 0; michael@0: MP_DIGITS(&t5) = 0; michael@0: michael@0: MP_CHECKOK( mp_init(&a) ); michael@0: MP_CHECKOK( mp_init(&b) ); michael@0: MP_CHECKOK( mp_init(&t1) ); michael@0: MP_CHECKOK( mp_init(&t2) ); michael@0: MP_CHECKOK( mp_init(&t3) ); michael@0: MP_CHECKOK( mp_init(&t4) ); michael@0: MP_CHECKOK( mp_init(&t5) ); michael@0: michael@0: MP_CHECKOK( mpp_random_size(&a, preca) ); michael@0: MP_CHECKOK( mpp_random_size(&b, precb) ); michael@0: michael@0: if (mp_cmp(&a, &b) < 0) michael@0: mp_exch(&a, &b); michael@0: michael@0: MP_CHECKOK( mp_mod(&a, &b, &t1) ); /* t1 = a%b */ michael@0: MP_CHECKOK( mp_div(&a, &b, &t2, NULL) ); /* t2 = a/b */ michael@0: MP_CHECKOK( mp_mul(&b, &t2, &t3) ); /* t3 = (a/b)*b */ michael@0: MP_CHECKOK( mp_add(&t1, &t3, &t4) ); /* t4 = a%b + (a/b)*b */ michael@0: MP_CHECKOK( mp_sub(&t4, &a, &t5) ); /* t5 = a%b + (a/b)*b - a */ michael@0: if (mp_cmp_z(&t5) != 0) { michael@0: res = MP_UNDEF; michael@0: goto CLEANUP; michael@0: } michael@0: michael@0: CLEANUP: michael@0: mp_clear(&t5); michael@0: mp_clear(&t4); michael@0: mp_clear(&t3); michael@0: mp_clear(&t2); michael@0: mp_clear(&t1); michael@0: mp_clear(&b); michael@0: mp_clear(&a); michael@0: return res; michael@0: } michael@0: michael@0: int michael@0: main(void) michael@0: { michael@0: unsigned int seed = (unsigned int)time(NULL); michael@0: unsigned long count = 0; michael@0: mp_err res; michael@0: michael@0: srand(seed); michael@0: michael@0: while (MP_OKAY == (res = identity_test())) { michael@0: if ((++count % 100) == 0) michael@0: fputc('.', stderr); michael@0: } michael@0: michael@0: fprintf(stderr, "\ntest failed, err %d\n", res); michael@0: return res; michael@0: }