#Greatest Common Divisor ==> https://en.wikipedia.org/wiki/Euclidean_algorithm print("Greatest Common Divisor") a=66528 b=52920 def gcd(a, b): if a: return gcd(b%a, a) else: return b # while True: # if b == 0: # break # c = max(a, b) % min(a, b) # a = b # b = c # return a print(f"GCD({a}, {b}) = {gcd(a, b)}") print() #Extended GCD print("Extended GCD") p = 26513 q = 32321 def egcd(a, b): r = [a, b] s = [1, 0] t = [0, 1] while True: if r[1] == 0: break q = r[0]//r[1] r.append(r[0] % r[1]) s.append(s[0]-q*s[1]) t.append(t[0]-q*t[1]) r.pop(0) s.pop(0) t.pop(0) return r[0], s[0], t[0] r, s, t = egcd(p, q) print(f"EGCD({p}, {q}) : GCD = {r} = ({s}*{p}) + ({t}*{q})") print(f"flag = {min(s, t)}") print() #Modular Arithmetic 1 print("Modular Arithmetic 1") a = 11 m = 6 x = a%m a = 8146798528947 m = 17 y = a%m print("x = ", x) print("y = ", y) print(f"flag = {min(x, y)}") print() #Modular Arithmetic 2 print("Modular Arithmetic 2") def fermat(x, p): print(f"({x}^{p-1}) % {p} = {(x**(p-1))%p}") fermat(7, 17) fermat(273246787654, 65537) print() #Modular Inverting print("Modular Inverting") ''' Looking again at Fermat's little theorem... if p is prime, for every integer a: pow(a, p) = a mod p and, if p is prime and a is an integer coprime with p: pow(a, p-1) = 1 mod p We can do some magic like this: Note: i'll use math notation, so a^b means pow(a,b) a^(p-1) = 1 (mod p) a^(p-1) * a^-1 = a^-1 (mod p) a^(p-2) * a * a^-1 = a^-1 (mod p) a^(p-2) * 1 = a^-1 (mod p) So finally we have: a^(p-2) = a^-1 (mod p) So, doing a^(p-2) and then (mod p) we can achieve our result ''' a = 3 p = 13 print(f"flag = {(a**(p-2))%p}") print() #Quadratic Residues p = 29 ints = [14, 6, 11] for i in range(p): x = (i**2)%p print(f"{i}^2 % {p} = {x} ({x} is a Quadratic Residue {'***' if x in ints else ''})") #Legendre Symbol # Quadratic Residue * Quadratic Residue = Quadratic Residue # Quadratic Residue * Quadratic Non-residue = Quadratic Non-residue # Quadratic Non-residue * Quadratic Non-residue = Quadratic Residue