Search code examples
pythonlargenumber

simple python program with gmpy2 is crashing (but i can do in scala???) -> overflow in mpz type / Aborted (core dumped


I am running into an issue with the above mentioned library, running a very simple example -- which I can get working using similar libraries in JVM land (using Scala).

The Scala code snippet below prints 'good', while the python version dies with the error in the title of the post.

Wondering if this is a known bug.. or am i doing something silly in the Python version of the calculation ? thnx in advance !

Scala

import java.math.BigInteger

import java.nio.charset.StandardCharsets
import java.util.Base64


object Example extends App {
  val pstr: String ="134078079299425970995740249982058461274793658205923933" +
    "77723561443721764030073546976801874298166903427690031" +
    "858186486050853753882811946569946433649006084171"
  val gstr = "11717829880366207009516117596335367088558084999998952205"  +
    "59997945906392949973658374667057217647146031292859482967"  +
    "5428279466566527115212748467589894601965568"
  val hstr = "323947510405045044356526437872806578864909752095244"  +
    "952783479245297198197614329255807385693795855318053"  +
    "2878928001494706097394108577585732452307673444020333"


  val decodedBytes = Base64.getDecoder.decode("Mzc1Mzc0MjE3ODMw")
  val decodedString = new String(decodedBytes, StandardCharsets.UTF_8)     // obfuscated ... can't fall into wrong hands

  val p: BigInteger = new BigInteger(pstr)
  val g: BigInteger = new BigInteger(gstr)
  val h: BigInteger = new BigInteger(hstr)
  val exponent: BigInteger = new BigInteger(decodedString)

  val recover = g.modPow(exponent, p)

  if (recover == h)
    print("good")
  else
    print("bad")
}

Python version

import gmpy2
import base64

pstr = "134078079299425970995740249982058461274793658205923933" + \
       "77723561443721764030073546976801874298166903427690031" + \
       "858186486050853753882811946569946433649006084171"

gstr = "11717829880366207009516117596335367088558084999998952205" + \
       "59997945906392949973658374667057217647146031292859482967" + \
       "5428279466566527115212748467589894601965568"

hstr = "323947510405045044356526437872806578864909752095244" + \
       "952783479245297198197614329255807385693795855318053" + \
       "2878928001494706097394108577585732452307673444020333"

p = gmpy2.mpz(pstr)
g = gmpy2.mpz(gstr)
h = gmpy2.mpz(hstr)

secret_exponent_encoded = base64.b64decode(b'Mzc1Mzc0MjE3ODMw').decode('utf-8')
exponent = gmpy2.mpz(secret_exponent_encoded)
recover = (g ** exponent) % p

if (recover == h):
    print("true")
else:
    print("false")


Solution

  • Under gmpy2 version 2.2.0a1 I get this error instead:

       recover = (g** exponent)  % p
                   ^^~~~~~~~~~
    ValueError: pow() outrageous exponent
    

    That makes sense. There's not a computer on the planet with enough RAM to compute g**exponent here. The underlying library (GMP) does not handle out-of-memory gracefully - it just aborts the program.

    With the following change, though, it runs fine and prints true:

        #recover = (g** exponent)  % p
        recover = gmpy2.powmod(g, exponent, p)