예제 #1
0
 def _inv(s, a):
     if len(a) == 1:
         return Zmod._inv(s, a)
     a, b = map(int, a)
     if s.t == 1:
         u = a * a + b * b
         u = modinv(u, s.n)
         return s.element_class(s, a * u, -b * u)
     elif s.t == 2:
         u = a * a - a * b + b * b
         u = modinv(u, s.n)
         return s.element_class(s, (a - b) * u, (-b) * u)
예제 #2
0
def SSSA_Attack(F, E, P, Q):
    """
  Solve ECDLP using SSSA(Semaev-Smart-Satoh-Araki) Attack.
  Args:
    F: The Base Field
    E: The Elliptic Curve
    P: A point on E
    Q: A point on E
  Returns:
    Return x where satisfies Q = xP.
  """
    from .EllipticCurve import EllipticCurve
    from ecpy.fields import QQ, Zmod
    from ecpy.utils.util import modinv, is_enable_native, _native
    A = E.a
    # lP, lQ, ... is "lifted" P, Q, ...
    x1, y1 = hensel_lift(E, P)
    x2, y2 = hensel_lift(E, Q)
    lF = Zmod(F.p**2)
    lA = (y2 * y2 - y1 * y1 - (x2 * x2 * x2 - x1 * x1 * x1))
    lA = (lA * modinv(x2 - x1, lF.n)) % lF.n
    lB = (y1 * y1 - x1 * x1 * x1 - A * x1) % lF.n
    if not is_enable_native:
        modulo = F.p**2
        lE = EllipticCurve(lF, lA, lB)
        lP = lE(x1, y1)
        lQ = lE(x2, y2)
        lU = (F.p - 1) * lP
        lV = (F.p - 1) * lQ
        dx1 = ((int(lU.x) - x1) // F.p) % modulo
        dx2 = int(lU.y) - y1
        dy1 = ((int(lV.x) - x2) // F.p) % modulo
        dy2 = int(lV.y) - y2
        m = (dy1 * dx2 * modinv(dx1 * dy2, modulo)) % modulo
        return m % F.p
    else:
        modulo = F.p**2
        base = _native.FF(modulo)
        lE = _native.EC(base, lA, lB)
        lP = _native.EC_elem(lE, x1, y1)
        lQ = _native.EC_elem(lE, x2, y2)
        lU = _native.EC_elem(lE, 0, 1, 0)
        lV = _native.EC_elem(lE, 0, 1, 0)
        lE.mul(lU, lP, F.p - 1)
        lE.mul(lV, lQ, F.p - 1)
        lUx, lUy, lUz = lU.to_python()
        lVx, lVy, lVz = lV.to_python()
        lUx = (lUx * modinv(lUz, modulo)) % modulo
        lUy = (lUy * modinv(lUz, modulo)) % modulo
        lVx = (lVx * modinv(lVz, modulo)) % modulo
        lVy = (lVy * modinv(lVz, modulo)) % modulo
        dx1 = ((lUx - x1) // F.p) % modulo
        dx2 = lUy - y1
        dy1 = ((lVx - x2) // F.p) % modulo
        dy2 = lVy - y2
        m = (dy1 * dx2 * modinv(dx1 * dy2, modulo)) % modulo
        return m % F.p
예제 #3
0
def hensel_lift(curve, P):
    from six.moves import map
    """
  Calculate Lifted Point using Hensel's Lemma
  Args:
    curve: The Elliptic Curve
    P: A point on curve
  Returns:
    The "lifted" Point
  """
    from six.moves import map
    from ecpy.utils import modinv
    x, y, _ = map(int, tuple(P))
    p = curve.field.p
    t = (((x * x * x + curve.a * x + curve.b) - y * y) // p) % p
    t = (t * modinv(2 * y, p)) % p
    return list(map(int, (x, y + (curve.field.p * t))))
예제 #4
0
파일: root.py 프로젝트: elliptic-shiho/ecpy
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
예제 #5
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
예제 #6
0
파일: Zmod.py 프로젝트: elliptic-shiho/ecpy
 def _inv(s, a):
   return s.element_class(s, modinv(a[0], s.n))
예제 #7
0
 def _inv(s, a):
     return s.element_class(s, modinv(a[0], s.n))