Mathematica PowerMod反向和mp中的mpz_powm

时间:2014-08-13 02:39:50

标签: gmp number-theory modular-arithmetic

我在Mathematica中实现了一个使用PowerMod查找模块化逆的算法。我现在需要在C中实现这个算法,并且我决定使用gmp及其函数 mpz_powm ,这显然做了同样的事情。问题是,我没有得到相同的值。例如,在Mathematica上运行时,它会给出:

PowerMod[30030, -1, 43] = 35

mpz_pwm 给出16.并且:

PowerMod[30030, -1, 71] = 8

mpz_pwm 给出了46.(我希望这些是足够的例子。)我也尝试了各种模块化逆算法,我设法在网上找到它们,它们也提供不同的值。不过,我怀疑Mathematica是对的。有谁知道这里发生了什么?

2 个答案:

答案 0 :(得分:2)

this link有一些似乎相关的东西。

简而言之,似乎mpz_pwm将-1解释为无符号短路2 ^ 16-1。此链接的线程中的一个响应来自GMP开发人员,以及这是文档中的错误。

对于2 ^ 16-1,我通过一些实验来得到它。

PowerMod[30030,2^16-1,43]                                               

(* Out[5]= 16 *)

到目前为止一切顺利。当第三个参数是71时,它就会崩溃。但是PowerMod[30030, -1, 71]实际上不是8.当第三个参数是79时,它就成立。而我们仍然没有得到PowerMod[30030, 2^16-1,79]等于46:当第三个参数是73.所以我猜这些是你实际上分别提供给powerMod和mpz_pwm的参数。

如果GMP没有直接执行您需要的功能,您可以从扩展GCD获得模块化反转。我将展示在Mathematica中使用的代码,但我确信它可以适应手头的目的。

myModularInverse[n_,p_] := With[{inv=ExtendedGCD[n,p][[2,1]]},
  If[inv>0, inv, inv+p]]  

快速举例:

myModularInverse[30030, 43]                                            

(* Out[28]= 35 *)

myModularInverse[30030, 79]                                            

(* Out[29]= 8 *)

编辑:更多挖掘表明GMP有一个函数mpz_invert,似乎在这里做了所需的事情。请参阅GMP number theory functions。还有一个gmp_invert函数,我猜在gmp层次结构中处于更高级别。

答案 1 :(得分:1)

原生GMP mpz_powm不会直接处理负指数。您需要使用mpz_invert计算逆。

我在gmpy2(GMP的Python包装器)中实现了你想要的行为。我的代码在:

https://code.google.com/p/gmpy/source/browse/trunk/src/gmpy2_pow.c

注意代码:mpz_inoc和mpz_cloc是mpz_init和mpz_clear的替换,用于在幕后缓存对象。