0

I'm trying to write an implementation of Montgomery multiplication in Python and I need an equivalent to GMP's mpz_getlimbn() for Python longs but I can't for the life of me seem to find one.

Any help would be greatly appreciated.

Edit

I've implemented the following but I get index out of range errors for limbs which don't occur in GMP.

def unpack(x, b):
    if gmpy2:
        return [long(x) for x in gmpy2.unpack(gmpy2.mpz(x), b)]

    b = 2 ** b
    r = []
    while x:
        x, temp = divmod(x, b)
        r.append(temp)
    return r
Prydie
  • 1,807
  • 1
  • 20
  • 30
  • 1
    This is not part of the public API. See http://hg.python.org/cpython/file/db842f730432/Include/longintrepr.h for the implementation details you will have to reach into. – user2357112 May 09 '14 at 22:54
  • @user2357112 Thanks for your reply. Is there any way to dig into this without using Cython or is that the only route? – Prydie May 09 '14 at 23:55
  • I don't know enough about Cython to know if it's an appropriate tool to use here. I was thinking in terms of writing C directly. – user2357112 May 10 '14 at 04:02

1 Answers1

1

I modified your unpack() and it appears to work for me. If you still get an error, please post the full error.

>>> import gmpy2
>>> 
>>> def unpack(x, b):
...     try:
...         return [x for x in gmpy2.unpack(gmpy2.mpz(x), b)]
...     except NameError:
...         b = 2 ** b
...         r = []
...         while x:
...             x, temp = divmod(x, b)
...             r.append(temp)
...         return r
... 
>>> unpack(123456**7, 15)
[mpz(0), mpz(0), mpz(4096), mpz(25855), mpz(24508), mpz(31925), mpz(15111), mpz(10775)]
>>> del(gmpy2)
>>> unpack(123456**7, 15)
[0, 0, 4096, 25855, 24508, 31925, 15111, 10775]

When using gmpy2, I left the results as mpz to show that gmpy2 was used.

Python's long integer type uses limbs that store either 15 or 30 bits. sys.int_info will provide the specifics for your system.

BTW, I maintain gmpy2 and it's nice to see someone use unpack().

casevh
  • 11,093
  • 1
  • 24
  • 35
  • Thanks for your reply and thanks for the great library. In the docs for `mpz_getlimbn()` it states "The least significant limb is number 0" from what I can gather one must reverse the output of unpack to match this functionality right? – Prydie May 10 '14 at 08:23
  • Actually cancel that my unit tests now seem to pass without the reversing of the output of unpack. – Prydie May 10 '14 at 08:38