Ejemplo n.º 1
0
def generate_smooth(number, factor_base):
        result = []
        start = calculate_start(number)
        end = calculate_end(number)
        sieve = np.array([x**2-number for x in range(start,end)], 
                         copy = False, 
                         order = 'C')
        xs = []
        ys = []
        for factor in factor_base:
                roots = []
                if 2 == factor:
                        roots = [modsqrt(number, factor)]
                        # ring formed by mod 2 only has one root
                else:
                        first_root = modsqrt(number, factor)
                        roots = [first_root, factor - first_root]
                for root in roots:
                        s = math.ceil(start / factor) * factor - start
                        for ind in [s-root,s+root]:
                                index = int(ind) # for python2
                                while index < end - start:
                                        if 0 <= index:
                                                sieve[index] = factor_out(sieve[index], factor)
                                                if sieve[index] == 1:
                                                        xs.append(index+start)
                                                        ys.append((index+start)**2-number)
                                                        if len(xs) > len(factor_base) + 30:
                                                                return (xs, ys)
                                        index = index + factor

        return (xs,ys)
Ejemplo n.º 2
0
def roots_loop(g, deg_g, p, Fp):
    if deg_g == 0:
        return []
    if deg_g == 1:
        return [(-g[0]/g[1]).toInteger()]
    elif deg_g == 2:
        d = g[1]*g[1]-4*g[0]
        e = arith1.modsqrt(d.toInteger(), p)
        g1 = -g[1]
        g2 = 2*g[2]
        return [((g1 - e) / g2).toInteger(), ((g1 + e) / g2).toInteger()]
    deg_h = 0
    x = uniutil.FinitePrimeFieldPolynomial({0:-1, (p-1)//2:1}, Fp)
    a = 0
    while deg_h == 0 or deg_h == deg_g:
        b = uniutil.FinitePrimeFieldPolynomial({0:-a, 1:1}, Fp)
        v = g(b)
        h = x.gcd(v)
        a = a + 1
        deg_h = h.degree()
    b = uniutil.FinitePrimeFieldPolynomial({0:a-1, 1:1}, Fp)
    s = h(b)
    deg_s = deg_h
    t = g.exact_division(s)
    deg_t = t.degree()
    return roots_loop(s, deg_s, p, Fp) + roots_loop(t, deg_t, p, Fp)
Ejemplo n.º 3
0
def roots_loop(g, deg_g, p, Fp):
    if deg_g == 0:
        return []
    if deg_g == 1:
        return [(-g[0] / g[1]).toInteger()]
    elif deg_g == 2:
        d = g[1] * g[1] - 4 * g[0]
        e = arith1.modsqrt(d.toInteger(), p)
        g1 = -g[1]
        g2 = 2 * g[2]
        return [((g1 - e) / g2).toInteger(), ((g1 + e) / g2).toInteger()]
    deg_h = 0
    x = uniutil.FinitePrimeFieldPolynomial({0: -1, (p - 1) >> 1: 1}, Fp)
    a = 0
    while deg_h == 0 or deg_h == deg_g:
        b = uniutil.FinitePrimeFieldPolynomial({0: -a, 1: 1}, Fp)
        v = g(b)
        h = x.gcd(v)
        a = a + 1
        deg_h = h.degree()
    b = uniutil.FinitePrimeFieldPolynomial({0: a - 1, 1: 1}, Fp)
    s = h(b)
    deg_s = deg_h
    t = g.exact_division(s)
    deg_t = t.degree()
    return roots_loop(s, deg_s, p, Fp) + roots_loop(t, deg_t, p, Fp)
Ejemplo n.º 4
0
def cornacchia(d, p):
    """
    Return the solution of x^2 + d * y^2 = p .
    p be a prime and d be an integer such that 0 < d < p.
    """
    if (d <= 0) or (d >= p):
        raise ValueError("invalid input")
    k = arith1.legendre(-d, p)
    if k == -1:
        raise ValueError("no solution")
    x0 = arith1.modsqrt(-d, p)
    if x0 < (p / 2):
        x0 = p - x0
    a = p
    b = x0
    l = arith1.floorsqrt(p)
    while b > l:
        a, b = b, a % b
    c, r = divmod(p - b * b, d)
    if r:
        raise ValueError("no solution")
    t = arith1.issquare(c)
    if t == 0:
        raise ValueError("no solution")
    else:
        return (b, t)
Ejemplo n.º 5
0
def cornacchia(d, p):
    """
    Return the solution of x^2 + d * y^2 = p .
    p be a prime and d be an integer such that 0 < d < p.
    """
    if (d <= 0) or (d >= p):
        raise ValueError("invalid input")
    k = arith1.legendre(-d, p)
    if k == -1:
        raise ValueError("no solution")
    x0 = arith1.modsqrt(-d, p)
    if x0 < (p / 2):
        x0 = p - x0
    a = p
    b = x0
    l = arith1.floorsqrt(p)
    while b > l:
        a, b = b, a % b
    c, r = divmod(p - b * b, d)
    if r:
        raise ValueError("no solution")
    t = arith1.issquare(c)
    if t == 0:
        raise ValueError("no solution")
    else:
        return (b, t)
Ejemplo n.º 6
0
def cornacchiamodify(d, p):
    """
    Algorithm 26 (Modified cornacchia)
    Input : p be a prime and d be an integer such that d < 0 and d > -4p with
            d = 0, 1 (mod 4)
    Output : the solution of u^2 -d * v^2 = 4p.
    """
    q = 4 * p
    if (d >= 0) or (d <= -q):
        raise ValueError("invalid input")
    if p == 2:
        b = arith1.issquare(d + 8)
        if b:
            return (b, 1)
        else:
            raise ValueError("no solution")
    if arith1.legendre(d, p) == -1:
        raise ValueError("no solution")
    x0 = arith1.modsqrt(d, p)
    if (x0 - d) & 1:
        x0 = p - x0
    a = 2 * p
    b = x0
    l = arith1.floorsqrt(q)
    while b > l:
        a, b = b, a % b
    c, r = divmod(q - b * b, -d)
    if r:
        raise ValueError("no solution")
    t = arith1.issquare(c)
    if t:
        return (b, t)
    else:
        raise ValueError("no solution")
Ejemplo n.º 7
0
def cornacchiamodify(d, p):
    """
    Algorithm 26 (Modified cornacchia)
    Input : p be a prime and d be an integer such that d < 0 and d > -4p with
            d = 0, 1 (mod 4)
    Output : the solution of u^2 -d * v^2 = 4p.
    """
    q = 4 * p
    if (d >= 0) or (d <= -q):
        raise ValueError("invalid input")
    if p == 2:
        b = arith1.issquare(d + 8)
        if b:
            return (b, 1)
        else:
            raise ValueError("no solution")
    if arith1.legendre(d, p) == -1:
        raise ValueError("no solution")
    x0 = arith1.modsqrt(d, p)
    if (x0 - d) % 2 != 0:
        x0 = p - x0
    a = 2 * p
    b = x0
    l = arith1.floorsqrt(q)
    while b > l:
        a, b = b, a % b
    c, r = divmod(q - b * b, -d)
    if r:
        raise ValueError("no solution")
    t = arith1.issquare(c)
    if t:
        return (b, t)
    else:
        raise ValueError("no solution")
Ejemplo n.º 8
0
 def SquareRoot(self, element):
     """ Return square root if exist.
     """
     if not element or element.n == 1:
         return element  # trivial case
     if element.m == 2:
         return element.getRing().one
     return arith1.modsqrt(element.n, element.m)
Ejemplo n.º 9
0
 def SquareRoot(self, element):
     """ Return square root if exist.
     """
     if not element or element.n == 1:
         return element # trivial case
     if element.m == 2:
         return element.getRing().one
     return arith1.modsqrt(element.n, element.m)
Ejemplo n.º 10
0
    def random_point(self):
        """

        Returns:
            A random point on the curve.
        """
        x = random.randrange(self.p)
        y_square = x**3 + self.a * x + self.b
        while jacobi(y_square, self.p) == -1:
            x = random.randrange(self.p)
            y_square = x**3 + self.a * x + self.b
        y = modsqrt(y_square, self.p)
        return x,
    def random_point(self):
        """

        Returns:
            A random point on the curve.
        """
        x = random.randrange(self.p)
        y_square = x**3 + self.a * x + self.b
        while jacobi(y_square, self.p) == -1:
            x = random.randrange(self.p)
            y_square = x**3 + self.a * x + self.b
        y = modsqrt(y_square, self.p)
        return x,
Ejemplo n.º 12
0
 def choose_point(self):
     """
     Choose point on E_{a,b}(Z_n)
     Algorithm 27 (Atkin-morain ECPP) Step5
     """
     n, f = self.modulus, self.f
     x = bigrandom.randrange(n)
     Q = f(x)
     while arith1.legendre(Q, n) == -1:
         x = bigrandom.randrange(n)
         Q = f(x)
     y = arith1.modsqrt(Q, n)
     return [intresidue.IntegerResidueClass(t, n) for t in (x, y)]
Ejemplo n.º 13
0
 def choose_point(self):
     """
     Choose point on E_{a,b}(Z_n)
     Algorithm 27 (Atkin-morain ECPP) Step5
     """
     n, f = self.modulus, self.f
     x = bigrandom.randrange(n)
     Q = f(x)
     while arith1.legendre(Q, n) == -1:
         x = bigrandom.randrange(n)
         Q = f(x)
     y = arith1.modsqrt(Q, n)
     return [intresidue.IntegerResidueClass(t, n) for t in (x, y)]
Ejemplo n.º 14
0
def root_Fp(g, p, flag=True):
    """
    Return a root over F_p of nonzero polynomial g.
    p must be prime.
    If flag = False, return a root randomly
    """
    if isinstance(g, list):
        if not isinstance(g[0], tuple):
            g = zip(range(len(g)), g)
    Fp = finitefield.FinitePrimeField(p)
    g = uniutil.FinitePrimeFieldPolynomial(g, Fp)
    h = uniutil.FinitePrimeFieldPolynomial({1: -1, p: 1}, Fp)
    g = g.gcd(h)
    deg_g = g.degree()
    if g[0] == 0:
        deg_g = deg_g - 1
        g = g.shift_degree_to(deg_g)
    while True:
        if deg_g == 0:
            return None
        if deg_g == 1:
            return (-g[0] / g[1]).toInteger()
        elif deg_g == 2:
            d = g[1] * g[1] - 4 * g[0]
            e = arith1.modsqrt(d.toInteger(), p)
            return ((-g[1] - e) / (2 * g[2])).toInteger()
        deg_h = 0
        x = uniutil.FinitePrimeFieldPolynomial({0: -1, (p - 1) >> 1: 1}, Fp)
        if flag:
            a = 0
            while deg_h == 0 or deg_h == deg_g:
                b = uniutil.FinitePrimeFieldPolynomial({0: -a, 1: 1}, Fp)
                v = g(b)
                h = x.gcd(v)
                a = a + 1
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0: a - 1, 1: 1}, Fp)
        else:
            while deg_h == 0 or deg_h == deg_g:
                a = bigrandom.randrange(p)
                b = uniutil.FinitePrimeFieldPolynomial({0: -a, 1: 1}, Fp)
                v = g(b)
                h = x.gcd(v)
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0: a, 1: 1}, Fp)
        g = h(b)
        deg_g = deg_h
Ejemplo n.º 15
0
def root_Fp(g, p, flag=True):
    """
    Return a root over F_p of nonzero polynomial g.
    p must be prime.
    If flag = False, return a root randomly
    """
    if isinstance(g, list):
        if not isinstance(g[0], tuple):
            g = zip(range(len(g)), g)
    Fp = finitefield.FinitePrimeField(p)
    g = uniutil.FinitePrimeFieldPolynomial(g, Fp)
    h = uniutil.FinitePrimeFieldPolynomial({1:-1, p:1}, Fp)
    g = g.gcd(h)
    deg_g = g.degree()
    if g[0] == 0:
        deg_g = deg_g - 1
        g = g.shift_degree_to(deg_g) 
    while True:
        if deg_g == 0:
            return None
        if deg_g == 1:
            return (-g[0]/g[1]).toInteger()
        elif deg_g == 2:
            d = g[1]*g[1] - 4*g[0]
            e = arith1.modsqrt(d.toInteger(), p)
            return ((-g[1]-e)/(2*g[2])).toInteger()
        deg_h = 0
        x = uniutil.FinitePrimeFieldPolynomial({0:-1, (p-1)//2:1}, Fp)
        if flag:
            a = 0
            while deg_h == 0 or deg_h == deg_g:
                b = uniutil.FinitePrimeFieldPolynomial({0:-a, 1:1}, Fp)
                v = g(b)
                h = x.gcd(v)
                a = a + 1
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0:a-1, 1:1}, Fp)
        else:
            while deg_h == 0 or deg_h == deg_g:
                a = bigrandom.randrange(p)
                b = uniutil.FinitePrimeFieldPolynomial({0:-a, 1:1}, Fp)
                v = g(b)
                h = x.gcd(v)
                deg_h = h.degree()
                b = uniutil.FinitePrimeFieldPolynomial({0:a, 1:1}, Fp)
        g = h(b)
        deg_g = deg_h
Ejemplo n.º 16
0
def cornacchia_smith(p, d):
    '''
    modified Cornacchia's Algorithm to solve a^2 + b^2 |D| = 4p for a and b
    Args:
        p:
        d:

    Returns:
        a, b such that a^2 + b^2 |D| = 4p

    '''
    # check input
    if not -4 * p < d < 0:
        raise ValueError(" -4p < D < 0 not true.")
    elif not (d % 4 in {0, 1}):
        raise ValueError(" D = 0, 1 (mod 4) not true.")

    # case where p=2
    if p == 2:
        r = sqrt(d + 8)
        if r != -1:
            return r, 1
        else:
            return None
    # test for solvability
    if jacobi(d % p, p) < 1:
        return None

    x = modsqrt(d, p)
    if (x % 2) != (d % 2):
        x = p - x
    # euclid chain
    a, b = (2 * p, x)
    c = floorsqrt(4 * p)
    while b > c:
        a, b = b, a % b

    t = 4 * p - b * b
    if t % (-d) != 0:
        return None
    if not issquare(t / (-d)):
        return None
    return b, int(mpmath.sqrt(t / -d))
Ejemplo n.º 17
0
def choose_point(ec):
    """
    Choose a random point on EC.
    Adapted from random_point function. With the additional check for modsqrt.
    Args:
        ec: an elliptic curve by the equation y^2 = x^3 + a * x + b

    Returns:
        a valid point on the curve.
    """
    x = random.randrange(ec.p)
    y_square = (x**3 + ec.a * x + ec.b) % ec.p
    while jacobi(y_square, ec.p) == -1:
        x = random.randrange(ec.p)
        y_square = (x**3 + ec.a * x + ec.b) % ec.p
    y = modsqrt(y_square, ec.p)

    if (y**2 % ec.p) != y_square:
        raise ValueError("Error computing square root.")

    return x, y
Ejemplo n.º 18
0
def sqroot_power(a, p, n):
    """
    return squareroot of a mod p^k for k = 2,3,...,n
    """
    r = arith1.modsqrt(a, p)
    x = (r, p-r)
    i = 2
    answer = [x]
    ppower = p
    while i <= n:
        b_1 = (x[0]**2-a) // ppower
        b_2 = (x[1]**2-a) // ppower
        x_1 = -b_1 * arith1.inverse(2*x[0], p)
        x_2 = -b_2 * arith1.inverse(2*x[1], p)
        X_1 = x[0] + x_1*ppower % (p*ppower)
        X_2 = x[1] + x_2*ppower % (p*ppower)
        x = [X_1, X_2]
        answer.append(x)
        i += 1
        ppower *= p
    return answer
Ejemplo n.º 19
0
def sqroot(disc, p):
    """
    Return a reduced quadratic form with the given discriminant.
    'disc' is a quadratic residue mod 'p'.
    """
    if p == 2: # if 8 | disc => (disc / 8) = 0, 8 not | disc but 4 | disc => 2
        if (disc % 8) == 0:
            bp = disc
        elif (disc % 4) == 0: # 4 - 4 * odd % 8 => 0
            bp = 2
        elif (disc % 8) == 1: # disc is odd and disc % 8 is 1
            bp = disc
        else: # disc is odd and disc % 4 is 1 => impossible (-5 / 2) = -1
            raise ValueError("disc is odd and disc % 4 is 1 => impossible (-5 / 2) = -1")
    else:
        bpf1 = arith1.modsqrt(disc, p)
        bpf2 = disc
        bp = crt([(bpf1, p), (bpf2, 4)])
    if bp > p:
        bp = 2 * p - bp

    fpt = reducePDF((p, bp, ((bp ** 2) - disc) // (4 * p)))
    return fpt
Ejemplo n.º 20
0
def e2_Fp(x, p):
    """
    p is prime
    f = x[0] + x[1]*t + x[2]*t**2
    """
    c, b, a = [_x % p for _x in x]
    if a == 0:
        return [e1_ZnZ([c, b], p)]
    if p == 2:
        solutions = []
        if x[0] & 1 == 0:
            solutions.append(0)
        if (x[0] + x[1] + x[2]) & 1 == 0:
            solutions.append(1)
        if len(solutions) == 1:
            return solutions * 2
        return solutions
    d = b**2 - 4 * a * c
    if arith1.legendre(d, p) == -1:
        return []
    sqrtd = arith1.modsqrt(d, p)
    a = arith1.inverse(2 * a, p)
    return [((-b + sqrtd) * a) % p, ((-b - sqrtd) * a) % p]
Ejemplo n.º 21
0
def e2_Fp(x, p):
    """
    p is prime
    f = x[0] + x[1]*t + x[2]*t**2
    """
    c, b, a = [_x % p for _x in x]
    if a == 0:
        return [e1_ZnZ([c, b], p)]
    if p == 2:
        solutions = []
        if x[0] % 2 == 0:
            solutions.append(0)
        if (x[0] + x[1] + x[2]) % 2 == 0:
            solutions.append(1)
        if len(solutions) == 1:
            return solutions * 2
        return solutions
    d = b**2 - 4*a*c
    if arith1.legendre(d, p) == -1:
        return []
    sqrtd = arith1.modsqrt(d, p)
    a = arith1.inverse(2*a, p)
    return [((-b+sqrtd)*a)%p, ((-b-sqrtd)*a)%p]
Ejemplo n.º 22
0
def sqroot(disc, p):
    """
    Return a reduced quadratic form with the given discriminant.
    'disc' is a quadratic residue mod 'p'.
    """
    if p == 2:  # if 8 | disc => (disc / 8) = 0, 8 not | disc but 4 | disc => 2
        if (disc & 7) == 0:
            bp = disc
        elif (disc & 3) == 0:  # 4 - 4 * odd % 8 => 0
            bp = 2
        elif (disc & 7) == 1:  # disc is odd and disc % 8 is 1
            bp = disc
        else:  # disc is odd and disc & 3 is 1 => impossible (-5 / 2) = -1
            raise ValueError(
                "disc is odd and disc & 3 is 1 => impossible (-5 / 2) = -1")
    else:
        bpf1 = arith1.modsqrt(disc, p)
        bpf2 = disc
        bp = crt([(bpf1, p), (bpf2, 4)])
    if bp > p:
        bp = 2 * p - bp

    fpt = reducePDF((p, bp, ((bp**2) - disc) // (4 * p)))
    return fpt
Ejemplo n.º 23
0
 def testModsqrt(self):
     self.assertTrue(arith1.modsqrt(2, 17) in (6, 11))
     self.assertTrue(arith1.modsqrt(124413, 2**17 - 1) in (3998, 127073))
     self.assertEqual(1, arith1.modsqrt(1, 2**13 - 1))
     self.assertTrue(arith1.modsqrt(2, 7, 2) in (10, 39))
     self.assertTrue(arith1.modsqrt(12, 97, 3) in (448799, 463874))