def roca(n): keySize = n.bit_length() if keySize <= 960: M_prime = 0x1B3E6C9433A7735FA5FC479FFE4027E13BEA m = 5 elif 992 <= keySize <= 1952: M_prime = ( 0x24683144F41188C2B1D6A217F81F12888E4E6513C43F3F60E72AF8BD9728807483425D1E ) m = 4 print("Have you several days/months to spend on this ?") elif 1984 <= keySize <= 3936: M_prime = 0x16928DC3E47B44DAF289A60E80E1FC6BD7648D7EF60D1890F3E0A9455EFE0ABDB7A748131413CEBD2E36A76A355C1B664BE462E115AC330F9C13344F8F3D1034A02C23396E6 m = 7 print("You'll change computer before this scripts ends...") elif 3968 <= keySize <= 4096: print("Just no.") return None else: print("Invalid key size: {}".format(keySize)) return None beta = 0.1 a3 = Zmod(M_prime)(n).log(65537) order = Zmod(M_prime)(65537).multiplicative_order() inf = a3 >> 1 sup = (a3 + order) >> 1 # Upper bound for the small root x0 XX = floor(2 * n ** 0.5 / M_prime) invmod_Mn = inverse_mod(M_prime, n) # Create the polynom f(x) F = PolynomialRing(Zmod(n), implementation="NTL", names=("x",)) (x,) = F._first_ngens(1) # Search 10 000 values at a time, using multiprocess # too big chunks is slower, too small chunks also chunk_size = 10000 for inf_a in range(inf, sup, chunk_size): # create an array with the parameter for the solve function inputs = [ ((M_prime, n, a, m, XX, invmod_Mn, F, x, beta), {}) for a in range(inf_a, inf_a + chunk_size) ] # the sage builtin multiprocessing stuff from sage.parallel.multiprocessing_sage import parallel_iter from multiprocessing import cpu_count for k, val in parallel_iter(cpu_count(), solve, inputs): if val: p = val[0] q = val[1] print("{}:{}".format(p, q)) return val return "Fail"
def coeffs_to_poly(c_string): """Given a string of coefficients, returns the polynomial with those coefficients INPUT: c_string -- string, a a comma-separated string (with no spaces) of rational numbers OUTPUT: The polynomial with these coefficients """ R = PolynomialRing(QQ, names=('x', )) (x, ) = R._first_ngens(1) tup = eval(c_string) return sum([tup[i] * x**i for i in range(0, len(tup))])
def coeffs_to_poly(c_string): """Given a string of coefficients, returns the polynomial with those coefficients INPUT: c_string -- string, a a comma-separated string (with no spaces) of rational numbers OUTPUT: The polynomial with these coefficients """ R = PolynomialRing(QQ, names=('x',)) (x,) = R._first_ngens(1) tup = eval(c_string) return sum([tup[i]*x**i for i in range(0,len(tup))])
def solve(M, n, a, m): # I need to import it in the function otherwise multiprocessing doesn't find it in its context from sage_functions import coppersmith_howgrave_univariate base = int(65537) # the known part of p: 65537^a * M^-1 (mod N) known = int(pow(base, a, M) * inverse_mod(M, n)) # Create the polynom f(x) F = PolynomialRing(Zmod(n), implementation="NTL", names=("x",)) (x,) = F._first_ngens(1) pol = x + known beta = 0.1 t = m + 1 # Upper bound for the small root x0 XX = floor(2 * n ** 0.5 / M) # Find a small root (x0 = k) using Coppersmith's algorithm roots = coppersmith_howgrave_univariate(pol, n, beta, m, t, XX) # There will be no roots for an incorrect guess of a. for k in roots: # reconstruct p from the recovered k p = int(k * M + pow(base, a, M)) if n % p == 0: return p, n // p