def privatekey_check(N, p, q, d, e): ret = False txt = "" nlen = getpubkeysz(N) if is_prime(p) == False: ret = True txt += "p IS NOT PROBABLE PRIME\n" if is_prime(q) == False: txt = "q IS NOT PROBABLE PRIME\n" if gcd(p, e) > 1: ret = True txt = "p and e ARE NOT RELATIVELY PRIME\n" if gcd(q, e) > 1: ret = True txt += "q and e ARE NOT RELATIVELY PRIME\n" if p * q != N: ret = True txt += "n IS NOT p * q\n" if not (abs(p - q) > (2**((nlen >> 1) - 100))): ret = True txt += "|p - q| IS NOT > 2^(nlen/2 - 100)\n" if not (p > 2**((nlen >> 1) - 1)): ret = True txt += "p IS NOT > 2^(nlen/2 - 1)\n" if not (q > 2**((nlen >> 1) - 1)): ret = True txt += "q IS NOT > 2^(nlen/2 - 1)\n" if not (d > 2**(nlen >> 1)): ret = True txt += "d IS NOT > 2^(nlen/2)\n" if not (d < lcm(p - 1, q - 1)): ret = True txt += "d IS NOT < lcm(p-1,q-1)\n" unc = (gcd(e - 1, p - 1) + 1) * (gcd(e - 1, q - 1) + 1) if unc > 9: ret = True txt += "The number of unconcealed messages is %d > min\n" % unc try: inv = invert(e, lcm(p - 1, q - 1)) except: inv = None ret = True txt += "e IS NOT INVERTIBLE mod lcm(p-1,q-1)\n" if d != inv: ret = True txt += "d IS NOT e^(-1) mod lcm(p-1,q-1)" return (ret, txt)
def pre_attack_check(self, publickeys): """Basic pre Attack checks implementation""" if not isinstance(publickeys, list): publickeys = [publickeys] tmp = [] ok = True for publickey in publickeys: if publickey.n & 1 == 0: self.logger.error("[!] Public key: %s modulus should be odd." % publickey.filename) ok = False if gcd(publickey.n, publickey.e) > 1: self.logger.error( "[!] Public key: %s modulus is coprime with exponent." % publickey.filename) ok = False if not (publickey.n > 3): self.logger.error("[!] Public key: %s modulus should be > 3." % publickey.filename) ok = False if is_prime(publickey.n): self.logger.error( "[!] Public key: %s modulus should not be prime." % publickey.filename) ok = False i = isqrt(publickey.n) if publickey.n == (i**2): self.logger.error( "[!] Public key: %s modulus should not be a perfect square." % publickey.filename) publickey.p = i publickey.q = i tmp.append(publickey) ok = False return (tmp, ok)
def pollard_rho(self, n, seed=2, p=2, mode=1): if n & 1 == 0: return 2 if n % 3 == 0: return 3 if n % 5 == 0: return 5 if is_prime(n): return n if mode == 1: f = lambda x: x**p + 1 else: f = lambda x: x**p - 1 x, y, d = seed, seed, 1 while d == 1: x = f(x) % n y = f(f(y)) % n d = gcd((x - y) % n, n) return None if d == n else d
def dixon_factor(N, B=7, explain=False): if is_prime(N): return N, 1 start = isqrt(N) if (start ** 2) == N: return start, start base = primes(B) lqbf = pow(base[-1], 2) + 1 QBF = bitarray.bitarray(lqbf) # This is our quasi-bloom-filter basej2N = [] for j in range(0, len(base)): p = powmod(base[j], 2, N) basej2N.append(p) QBF[p] = 1 # We populate our quasi-bloom-filter i = start while i < N: i2N = pow(i, 2, N) if i2N < lqbf and QBF[i2N] == 1: for k in range(0, len(base)): if QBF[basej2N[k]] == 1: # if i2N == basej2N[k]: # this is replaced with a quasi-bloom-filter f = gcd(i - base[k], N) if explain: print("N = %d" % N) print("%d = isqrt(N)" % start) print("%d = pow(%d,2,n)" % (i2N, i)) print("%d = pow(%d,2,n)" % (basej2N[k], base[k])) print("%d - %d = %d" % (i, base[k], f)) print("%d = gcd(%d - % d, N)" % (f, i, base[k])) print( "%d = gcd(%d + % d, N)" % (gcd(i + base[k], N), i, base[k]) ) if 1 < f < N: return f, N // f i += 1 return None, None