def strong_pseudo(b, n): for m in range(1, n): r = int(log2((n - 1)//m)) e = modexp(b, m, n) for s in range(1, r): e2 = modexp(b, exp(2, s)*m, n) if e == 1 or e2 == -1: print('Strong pseudoprime m={}, r={}, s={}'.format(m, r, s), end=" ") if e == 1: print('(condition 1)') if e == -1: print('(condition 2)')
def order(n, m): e = 1 found = False while not found: if modexp(n, e, m) == 1: found = True return e e += 1
def fermat(n): for x in range(1, n): a = modexp(x, n - 1, n) if a != 1: print('Composite') return False else: print('Pseudoprime, base', x) return True
def fermat2(n): pseudos = [] for x in range(1, n): a = modexp(x, n - 1, n) if a != 1: return (False, None) else: pseudos.append(x) return (True, pseudos)
def disc_log(a, b, p): m = int(p**0.5) + 1 # Ceiling print('m =', m) pairs = [] for j in range(m): g = modexp(a, j, p) print('giant step a^j: {}^{} = {}'.format(a, j, g)) pairs.append((j, g)) am = modexp(modinv(a, p), m, p) # a^(-m) mod p -> (a^(-1))^m mod p print('a^{-m} =', am) ajs = (list(zip(*pairs))[1]) y = b for i in range(m): s = (y*am) % p print('baby step y*am: {}*{} = {}'.format(y, am, s)) if y in ajs: return i*m + pairs[ajs.index(y)][0] # i*m + j else: y = s