Ejemplo n.º 1
0
def extended_legendre_symbol(a):
  """
  Legendre Symbol on the Extended Field
  Args:
    a: The Target
  Returns:
    Legendre Symbol of a
  """
  from six.moves import xrange
  from ecpy.utils import legendre_symbol
  m = a.field.degree()
  p = a.field.p
  b = pow(a, sum([p**i for i in xrange(0, m)]), p)
  return legendre_symbol(b, p)
Ejemplo n.º 2
0
def extended_legendre_symbol(a):
    """
  Legendre Symbol on the Extended Field
  Args:
    a: The Target
  Returns:
    Legendre Symbol of a
  """
    from six.moves import xrange
    from ecpy.utils import legendre_symbol
    m = a.field.degree()
    p = a.field.p
    b = pow(a, sum([p**i for i in xrange(0, m)]), p)
    return legendre_symbol(b, p)
Ejemplo n.º 3
0
def __modular_square_root(a, m):
  from ecpy.utils import is_prime, legendre_symbol, modinv
  if is_prime(m):
    if legendre_symbol(a, m) == -1:
      return []
    # Tonelli-Shanks Algorithm
    if m % 4 == 3:
      r = pow(a, (m + 1) // 4, m)
      return [r, m - r]
    s = _find_power_divisor(2, m - 1)
    q = (m - 1) // 2**s
    z = 0
    while legendre_symbol(z, m) != -1:
      z = random.randint(1, m)
    c = pow(z, q, m)
    r = pow(a, (q + 1) // 2, m)
    t = pow(a, q, m)
    l = s
    while True:
      if t % m == 1:
        assert (r ** 2) % m == a
        return [r, m - r]
      i = _find_power(2, t, 1, m)
      power = l - i - 1
      if power < 0:
        power = modinv(2**-power, m)
      else:
        power = 2**power
      b = pow(c, power, m)
      r = (r * b) % m
      t = (t * (b**2)) % m
      c = pow(b, 2, m)
      l = i
  if m == 2:
    return a
  if m % 4 == 3:
    r = pow(a, (m + 1) // 4, m)
    return [r, m - r]
  if m % 8 == 5:
    v = pow(2 * a, (m - 5) // 8, m)
    i = pow(2 * a * v, 2, m)
    r = a * v * (i - 1) % m
    return [r, m - r]
  if m % 8 == 1:
    e = _find_power_divisor(2, m - 1)
    q = (m - 1) // 2**e
    z = 1
    while pow(z, 2**(e - 1), m) == 1:
      x = random.randint(1, m)
      z = pow(x, q, m)
    y = z
    r = e
    x = pow(a, (q - 1) // 2, m)
    v = a * x % m
    w = v * x % m
    while True:
      if w == 1:
        return [v, m - v]
      k = _find_power(2, w, 1, m)
      d = pow(y, 2**(r - k - 1), m)
      y = pow(d, 2, m)
      r = k
      v = d * v % m
      w = w * y % m
Ejemplo n.º 4
0
def __modular_square_root(a, m):
    from ecpy.utils import is_prime, legendre_symbol, modinv
    if is_prime(m):
        if legendre_symbol(a, m) == -1:
            return []
        # Tonelli-Shanks Algorithm
        if m % 4 == 3:
            r = pow(a, (m + 1) // 4, m)
            return [r, m - r]
        s = _find_power_divisor(2, m - 1)
        q = (m - 1) // 2**s
        z = 0
        while legendre_symbol(z, m) != -1:
            z = random.randint(1, m)
        c = pow(z, q, m)
        r = pow(a, (q + 1) // 2, m)
        t = pow(a, q, m)
        l = s
        while True:
            if t % m == 1:
                assert (r**2) % m == a
                return [r, m - r]
            i = _find_power(2, t, 1, m)
            power = l - i - 1
            if power < 0:
                power = modinv(2**-power, m)
            else:
                power = 2**power
            b = pow(c, power, m)
            r = (r * b) % m
            t = (t * (b**2)) % m
            c = pow(b, 2, m)
            l = i
    if m == 2:
        return a
    if m % 4 == 3:
        r = pow(a, (m + 1) // 4, m)
        return [r, m - r]
    if m % 8 == 5:
        v = pow(2 * a, (m - 5) // 8, m)
        i = pow(2 * a * v, 2, m)
        r = a * v * (i - 1) % m
        return [r, m - r]
    if m % 8 == 1:
        e = _find_power_divisor(2, m - 1)
        q = (m - 1) // 2**e
        z = 1
        while pow(z, 2**(e - 1), m) == 1:
            x = random.randint(1, m)
            z = pow(x, q, m)
        y = z
        r = e
        x = pow(a, (q - 1) // 2, m)
        v = a * x % m
        w = v * x % m
        while True:
            if w == 1:
                return [v, m - v]
            k = _find_power(2, w, 1, m)
            d = pow(y, 2**(r - k - 1), m)
            y = pow(d, 2, m)
            r = k
            v = d * v % m
            w = w * y % m