Search code examples
python-3.xgmpy

Fastest way to convert gmpy2 mpz to a bigendian byte-array (bytes)?


I tried several different approaches, from

def ToByteArray(x):
    x = int(x)
    return x.to_bytes((x.bit_length() + 7) // 8, byteorder='big')

or diving x by 256 and building a new bytearray in a loop but it just feels slow compared to the conversion of a normal python int or in gmpy2 c++.

Isn't there something like an mpz_export in c++? What is the fastest way to accomplish this?

Edit: The reason I need to convert it to bytes is that hashlib cannot hash mpz. If there is another fast way to get a strong cryptographic (sha256) hash of an mpz, without having to convert it to bytes first, that might help aswell!


Solution

  • I think gmpy2.to_binary() will do what you need. It converts a gmpy2 object to portable byte sequence. It uses mpz_export to convert the underlying mpz_t to a sequence of bytes. A short header containing the gmpy2 type and the length is placed at the beginning of the byte sequence. For the gmpy2.mpz type (and assuming the value is not 0), the header is two bytes long.

    >>> gmpy2.to_binary(gmpy2.mpz(123456**7))
    b'\x01\x01\x00\x00\x00\x00\x00\xe4\x9f\xcc\xfb\xad\xe5\x1f\xec.T'