0

Please consider the following code:

mpz_t x, n, out;

mpz_init_set_ui(x, 2UL);
mpz_init_set_ui(n, 7UL);
mpz_init(out);

mpz_invert(out, x, n);
gmp_printf ("%Zd\n", out);//prints 4. 2 * 4 (mod 7) = 1. OK

mpz_powm_ui(out, x, -1, n);//prints 1. 2 * 1 (mod 7) = 2. How come?
gmp_printf ("%Zd\n", out);

mpz_clear(x);
mpz_clear(n);
mpz_clear(out);

I am unable to understand how the mpz_powm functions handle negative exponents, although, according to the documentation, it is supposed to support them. I would expect that raising a number to -1 modulo n is equivalent to inverting it modulo n. What am I missing here?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Mihai Todor
  • 8,014
  • 9
  • 49
  • 86

2 Answers2

1

Try to make -1 a signed number. In other words, don't use the unsigned interface, but make a real bignum with value -1.

To wit:

#include <gmpxx.h>
#include <iostream>

int main()
{
    mpz_class n(7), k(2), res;
    mpz_powm(res.get_mpz_t(), k.get_mpz_t(), mpz_class(-1).get_mpz_t(), n.get_mpz_t());
    std::cout << res << std::endl;
}

Prints:

4
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Ufff... Sorry about that. It's a copy / paste gone wrong issue. Unfortunately, the behavior is the same even after I remove it. – Mihai Todor Jun 24 '12 at 21:16
  • Indeed, it's an issue with the way `mpz_powm_ui` is declared. I just noticed the obvious fact that the exp parameter is declared as unsigned long in gmp.h. I will ask the GMP / MPIR developers why this is so. Thanks for helping me figure it out. – Mihai Todor Jun 24 '12 at 21:26
0

The problem is caused by the way in which the mpz_powm_ui function is declared:

void mpz_powm_ui (mpz t rop, mpz t base, unsigned long int exp, mpz t mod)

Perhaps this is a documentation bug, since exp will always be positive.

Mihai Todor
  • 8,014
  • 9
  • 49
  • 86
  • _ui at the end is a good indication that it takes an unsigned int. – Eve Freeman Jun 24 '12 at 21:29
  • Yes, indeed. The documentation is a bit misleading since it doesn't provide different descriptions for `mpz_powm` and `mpz_powm_ui`. Anyway, I'm happy that I finally managed to figure out what was causing my application to produce strange results. – Mihai Todor Jun 24 '12 at 21:36
  • Yeah, it probably should be split out, since the behavior is a bit different. – Eve Freeman Jun 24 '12 at 21:50