Search code examples
pythoncryptographygmpgmpy

Break python long into limbs


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

Solution

  • 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().