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]
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)
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)