Cube root modulo P - 我该怎么做?

Set*_*eth 10 python algorithm rsa modulo public-key-encryption

我试图在Python中计算数百个数字模P的立方根,并且失败了.

我找到了Tonelli-Shanks算法的代码,据说这个算法从平方根到立方根都很容易修改,但这让我望而却步.我搜索过网络和数学图书馆以及一些书都无济于事.代码会很精彩,算法也会用简单的英语解释.

这是用于查找平方根的Python(2.6?)代码:

def modular_sqrt(a, p):
    """ Find a quadratic residue (mod p) of 'a'. p
        must be an odd prime.

        Solve the congruence of the form:
            x^2 = a (mod p)
        And returns x. Note that p - x is also a root.

        0 is returned is no square root exists for
        these a and p.

        The Tonelli-Shanks algorithm is used (except
        for some simple cases in which the solution
        is known from an identity). This algorithm
        runs in polynomial time (unless the
        generalized Riemann hypothesis is false).
    """
    # Simple cases
    #
    if legendre_symbol(a, p) != 1:
        return 0
    elif a == 0:
        return 0
    elif p == 2:
        return n
    elif p % 4 == 3:
        return pow(a, (p + 1) / 4, p)

    # Partition p-1 to s * 2^e for an odd s (i.e.
    # reduce all the powers of 2 from p-1)
    #
    s = p - 1
    e = 0
    while s % 2 == 0:
        s /= 2
        e += 1

    # Find some 'n' with a legendre symbol n|p = -1.
    # Shouldn't take long.
    #
    n = 2
    while legendre_symbol(n, p) != -1:
        n += 1

    # Here be dragons!
    # Read the paper "Square roots from 1; 24, 51,
    # 10 to Dan Shanks" by Ezra Brown for more
    # information
    #

    # x is a guess of the square root that gets better
    # with each iteration.
    # b is the "fudge factor" - by how much we're off
    # with the guess. The invariant x^2 = ab (mod p)
    # is maintained throughout the loop.
    # g is used for successive powers of n to update
    # both a and b
    # r is the exponent - decreases with each update
    #
    x = pow(a, (s + 1) / 2, p)
    b = pow(a, s, p)
    g = pow(n, s, p)
    r = e

    while True:
        t = b
        m = 0
        for m in xrange(r):
            if t == 1:
                break
            t = pow(t, 2, p)

        if m == 0:
            return x

        gs = pow(g, 2 ** (r - m - 1), p)
        g = (gs * gs) % p
        x = (x * gs) % p
        b = (b * g) % p
        r = m

def legendre_symbol(a, p):
    """ Compute the Legendre symbol a|p using
        Euler's criterion. p is a prime, a is
        relatively prime to p (if p divides
        a, then a|p = 0)

        Returns 1 if a has a square root modulo
        p, -1 otherwise.
    """
    ls = pow(a, (p - 1) / 2, p)
    return -1 if ls == p - 1 else ls
Run Code Online (Sandbox Code Playgroud)

来源:计算模块化平方根源于Python

dei*_*nst 10

注意后来添加:在Tonelli-Shanks算法中,这里假设p是素数.如果我们能够快速地计算模块化平方根到复合模量,我们可以快速地计算数字.我为假设你知道p是素数而道歉.

这里这里.注意,以p为模的数是具有p个元素的有限域.

编辑:看到这个(这是那些论文的祖父.)

容易的部分是当p = 2 mod 3时,那么一切都是立方体,而a的立方根就是 a**((2*p-1)/3) %p

补充:这里是除了素数1 mod 9以外的所有代码.我将在本周末试着去做.如果没有其他人先到达它

#assumes p prime returns cube root of a mod p
def cuberoot(a, p):
    if p == 2:
        return a
    if p == 3:
        return a
    if (p%3) == 2:
        return pow(a,(2*p - 1)/3, p)
    if (p%9) == 4:
        root = pow(a,(2*p + 1)/9, p)
        if pow(root,3,p) == a%p:
            return root
        else:
            return None
    if (p%9) == 7:
        root = pow(a,(p + 2)/9, p)
        if pow(root,3,p) == a%p:
            return root
        else:
            return None
    else:
        print "Not implemented yet. See the second paper"
Run Code Online (Sandbox Code Playgroud)

  • 此代码提供三个立方根的**.如何获得另外两个? (2认同)
  • @SheblaTsama乘以1的原始立方根. (2认同)