예제 #1
0
 def as_polynomial_in_E4_and_E6(self,insert_in_db=True):
     r"""
     If self is on the full modular group writes self as a polynomial in E_4 and E_6.
     OUTPUT:
     -''X'' -- vector (x_1,...,x_n)
     with f = Sum_{i=0}^{k/6} x_(n-i) E_6^i * E_4^{k/4-i}
     i.e. x_i is the coefficient of E_6^(k/6-i)*
     """
     if(self.level() != 1):
         raise NotImplementedError("Only implemented for SL(2,Z). Need more generators in general.")
     if(self._as_polynomial_in_E4_and_E6 is not None and self._as_polynomial_in_E4_and_E6 != ''):
         return self._as_polynomial_in_E4_and_E6
     d = self._parent.dimension_modular_forms()  # dimension of space of modular forms
     k = self.weight()
     K = self.base_ring()
     l = list()
     # for n in range(d+1):
     #    l.append(self._f.q_expansion(d+2)[n])
     # v=vector(l) # (self._f.coefficients(d+1))
     v = vector(self.coefficients(range(d),insert_in_db=insert_in_db))
     d = dimension_modular_forms(1, k)
     lv = len(v)
     if(lv < d):
         raise ArithmeticError("not enough Fourier coeffs")
     e4 = EisensteinForms(1, 4).basis()[0].q_expansion(lv + 2)
     e6 = EisensteinForms(1, 6).basis()[0].q_expansion(lv + 2)
     m = Matrix(K, lv, d)
     lima = floor(k / 6)  # lima=k\6;
     if((lima - (k / 2)) % 2 == 1):
         lima = lima - 1
     poldeg = lima
     col = 0
     monomials = dict()
     while(lima >= 0):
         deg6 = ZZ(lima)
         deg4 = (ZZ((ZZ(k / 2) - 3 * lima) / 2))
         e6p = (e6 ** deg6)
         e4p = (e4 ** deg4)
         monomials[col] = [deg4, deg6]
         eis = e6p * e4p
         for i in range(1, lv + 1):
             m[i - 1, col] = eis.coefficients()[i - 1]
         lima = lima - 2
         col = col + 1
     if (col != d):
         raise ArithmeticError("bug dimension")
     # return [m,v]
     if self._verbose > 0:
         wmf_logger.debug("m={0}".format(m, type(m)))
         wmf_logger.debug("v={0}".format(v, type(v)))
     try:
         X = m.solve_right(v)
     except:
         return ""
     self._as_polynomial_in_E4_and_E6 = [poldeg, monomials, X]
     return [poldeg, monomials, X]
예제 #2
0
def attack(p, x1, y1, x2, y2):
    """
    Recovers the a and b parameters from an elliptic curve when two points are known.
    :param p: the prime of the curve base ring
    :param x1: the x coordinate of the first point
    :param y1: the y coordinate of the first point
    :param x2: the x coordinate of the second point
    :param y2: the y coordinate of the second point
    :return: a tuple containing the a and b parameters of the elliptic curve
    """
    m = Matrix(GF(p), [[x1, 1], [x2, 1]])
    v = vector(GF(p), [y1**2 - x1**3, y2**2 - x2**3])
    a, b = m.solve_right(v)
    return int(a), int(b)
예제 #3
0
def dsa_known_middle(n, signature1, signature2, nonce_bitsize, msb_unknown,
                     lsb_unknown):
    """
    Recovers the (EC)DSA private key and nonces if the middle nonce bits are known.
    This is a heuristic extension which might perform worse than the methods to solve the Extended Hidden Number Problem
    More information: De Micheli G., Heninger N., "Recovering cryptographic keys from partial information, by example" (Section 5.2.3)
    :param n: the modulus
    :param signature1: the first signature (a tuple of the message (hash), the r value, the s value, and the known middle bits)
    :param signature2: the second signature (a tuple of the message (hash), the r value, the s value, and the known middle bits)
    :param nonce_bitsize: the amount of bits of the nonces
    :param msb_unknown: the amount of unknown most significant bits of the nonces
    :param lsb_unknown: the amount of unknown least significant bits of the nonces
    :return: a tuple containing the private key, the nonce of the first signature, and the nonce of the second signature
    """
    unknown = max(msb_unknown, lsb_unknown)
    K = 2**unknown
    l = nonce_bitsize - msb_unknown

    h1, r1, s1, a1 = signature1
    h2, r2, s2, a2 = signature2
    t = -(pow(s1, -1, n) * s2 * r1 * pow(r2, -1, n))
    u = pow(s1, -1, n) * r1 * h2 * pow(r2, -1, n) - pow(s1, -1, n) * h1
    u_ = 2**lsb_unknown * a1 + 2**lsb_unknown * a2 * t + u

    B = Matrix(ZZ, 5)
    B[0] = vector(ZZ, [K, K * 2**l, K * t, K * t * 2**l, u_])
    B[1] = vector(ZZ, [0, K * n, 0, 0, 0])
    B[2] = vector(ZZ, [0, 0, K * n, 0, 0])
    B[3] = vector(ZZ, [0, 0, 0, K * n, 0])
    B[4] = vector(ZZ, [0, 0, 0, 0, K * n])

    B = B.LLL()

    M = Matrix(ZZ, 4)
    v = []
    for row, vec in enumerate(B[:4]):
        M[row] = vec[:4].apply_map(lambda x: x // K)
        v.append(-vec[4])

    x1, y1, x2, y2 = M.solve_right(vector(ZZ, v))

    k1 = 2**l * y1 + 2**lsb_unknown * a1 + x1
    k2 = 2**l * y2 + 2**lsb_unknown * a2 + x2
    private_key1 = pow(r1, -1, n) * (s1 * k1 - h1) % n
    private_key2 = pow(r2, -1, n) * (s2 * k2 - h2) % n
    assert private_key1 == private_key2

    return int(private_key1), int(k1), int(k2)