From 908e098cb3ee37fa5b18d650104cacb8d2854422 Mon Sep 17 00:00:00 2001 From: czurnieden Date: Wed, 7 Sep 2022 23:03:13 +0200 Subject: [PATCH] Fix: removed sign operation in s_mp_invmod_odd Changed a check for <0 with mp_isneg() in s_mp_invmod Additional tests for mp_invmod() in demo/test.c --- demo/test.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++ s_mp_invmod.c | 2 +- s_mp_invmod_odd.c | 5 +--- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/demo/test.c b/demo/test.c index 16fef5570..0ebcfd07f 100644 --- a/demo/test.c +++ b/demo/test.c @@ -549,6 +549,54 @@ static int test_mp_and(void) static int test_mp_invmod(void) { mp_int a, b, c, d; + int i, j, k; + int e; + + int results[21][21] = + /* Table generated with Pari/GP + + for(i=-10,10, + k=0; + d=0; + printf(" {"); + for(j=-10,10, + iferr( + printf(lift(Mod(1/i, j)) ", "), + k, + printf("-1, ")) + ); + print("},") + ) + + Changes to the output: replaced j < 1 with -1 for now and added the result of 0^(-1) mod (1) + + j = -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 */ + + { + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, 2, -1, 8, -1 }, /* i = -10 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 3, 1, -1, 3, 7, -1, 1 }, /* -9 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 3, -1, 6, -1, 1, -1 }, /* -8 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 1, 2, 5, -1, 1, 5, 7 }, /* -7 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, 1, -1, -1, -1 }, /* -6 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 3, -1, 1, 4, 3, 7, -1 }, /* -5 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, 1, -1, 5, -1, 2, -1 }, /* -4 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 3, -1, 2, 5, -1, 3 }, /* -3 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 2, -1, 3, -1, 4, -1 }, /* -2 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, /* -1 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* 0 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* 1 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 2, -1, 3, -1, 4, -1, 5, -1 }, /* 2 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 3, 2, -1, 5, 3, -1, 7 }, /* 3 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 4, -1, 2, -1, 7, -1 }, /* 4 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 1, -1, 5, 3, 5, 2, -1 }, /* 5 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, 6, -1, -1, -1 }, /* 6 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 3, 3, 1, -1, 7, 4, 3 }, /* 7 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 2, -1, 2, -1, 1, -1, 8, -1 }, /* 8 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, -1, 1, 4, -1, 4, 1, -1, 9 }, /* 9 */ + {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, -1, 5, -1, 1, -1 } /* 10 */ + }; + + DOR(mp_init_multi(&a, &b, &c, &d, NULL)); /* mp_invmod corner-case of https://github.com/libtom/libtommath/issues/118 */ @@ -564,6 +612,30 @@ static int test_mp_invmod(void) EXPECT(mp_cmp(&c, &d) == MP_EQ); } + /* Some small general tests https://github.com/libtom/libtommath/issues/534 */ + for (i = -10; i < 11; i++) { + for (j = -10; j < 11; j++) { + mp_set_i32(&a, i); + mp_set_i32(&b, j); + e = mp_invmod(&a, &b, &c); + if (e != MP_OKAY) { + if (results[i+10][j+10] != -1) { + printf("error = %s from ", mp_error_to_string(e)); + printf("error at i = %d, j =%d should be an error but gave ",i,j); + e = mp_fwrite(&c,10,stdout); + printf("\n"); + goto LBL_ERR; + } + } else { + k = mp_get_i32(&c); + if (k != results[i+10][j+10]) { + printf("result at i = %d, j =%d is %d but should be %d \n", i,j,k,results[i+10][j+10]); + goto LBL_ERR; + } + } + } + } + mp_clear_multi(&a, &b, &c, &d, NULL); return EXIT_SUCCESS; LBL_ERR: diff --git a/s_mp_invmod.c b/s_mp_invmod.c index f3b3f436f..b2fb21dee 100644 --- a/s_mp_invmod.c +++ b/s_mp_invmod.c @@ -98,7 +98,7 @@ mp_err s_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) } /* if its too low */ - while (mp_cmp_d(&C, 0uL) == MP_LT) { + while (mp_isneg(&C)) { if ((err = mp_add(&C, b, &C)) != MP_OKAY) goto LBL_ERR; } diff --git a/s_mp_invmod_odd.c b/s_mp_invmod_odd.c index e12dfa17f..11fc357dc 100644 --- a/s_mp_invmod_odd.c +++ b/s_mp_invmod_odd.c @@ -12,7 +12,6 @@ mp_err s_mp_invmod_odd(const mp_int *a, const mp_int *b, mp_int *c) { mp_int x, y, u, v, B, D; - mp_sign sign; mp_err err; /* 2. [modified] b must be odd */ @@ -28,7 +27,7 @@ mp_err s_mp_invmod_odd(const mp_int *a, const mp_int *b, mp_int *c) /* x == modulus, y == value to invert */ if ((err = mp_copy(b, &x)) != MP_OKAY) goto LBL_ERR; - /* we need y = |a| */ + /* y needs to be positive but the remainder d of mp_div(a,b,c,d) might be negative */ if ((err = mp_mod(a, b, &y)) != MP_OKAY) goto LBL_ERR; /* if one of x,y is zero return an error! */ @@ -95,7 +94,6 @@ mp_err s_mp_invmod_odd(const mp_int *a, const mp_int *b, mp_int *c) } /* b is now the inverse */ - sign = a->sign; while (mp_isneg(&D)) { if ((err = mp_add(&D, b, &D)) != MP_OKAY) goto LBL_ERR; } @@ -106,7 +104,6 @@ mp_err s_mp_invmod_odd(const mp_int *a, const mp_int *b, mp_int *c) } mp_exch(&D, c); - c->sign = sign; err = MP_OKAY; LBL_ERR: