General - Mathematics

Greatest Common Divisor

"The Greatest Common Divisor (GCD), sometimes known as the highest common factor, is the largest number which divides two positive integers (a,b).

Now calculate gcd(a,b) for a = 66528, b = 52920"

Lets make a simple implementation of Euclid's algorithm. All though it is always easier to use the math.gcd() function.

#!/usr/bin/env python3
def gcd(a, b):
    while b != 0:
        t = b
        b = a % b
        a = t

    return a

def main():
    a = 66528
    b = 52920
    print(gcd(a, b))

if __name__ == "__main__":
    main()

Extended GCD

"Let a and b be positive integers. The extended Euclidean algorithm is an efficient way to find integers u,v such that a * u + b * v = gcd(a,b)

Using the two primes p = 26513, q = 32321, find the integers u,v such that p * u + q * v = gcd(p,q)"

We can make a simple implementation like this:

#!/usr/bin/env python3

def extended_euclidean_algorithm(p, q):
    if q == 0:
        return (p, 1, 0)
    else:
        gcd, u, v = extended_euclidean_algorithm(q, p % q)
        return (gcd, v, u - (p // q) * v)

def main():
    p = 26513
    q = 32321
    gcd, u, v = extended_euclidean_algorithm(p, q)
    print("gcd(", p, ",", q, ") = ", gcd)
    print("u = ", u)
    print("v = ", v)

if __name__ == "__main__":
    main()

Or if we want a all the imidate steps of the calculation, we can use print them as a table like this:

from tabulate import tabulate

def extended_euclidean_algorithm(a, b):
    rounds = []
    ri = [a, b]
    qi = []
    si = []
    ti = []
    i = 0

    # First round
    rounds.append(i)
    qi.append('-')
    si.append(1)
    ti.append(0)
    i += 1

    while True:
        # Second round
        if i == 1:
            rounds.append(i)
            qi.append(a//b)
            si.append(0)
            ti.append(1)
        else:
            rounds.append(i)
            ri.append(b)
            qi.append(a//b)
            si.append(si[i-2] - qi[i - 1] * si[i-1])
            ti.append(ti[i-2] - qi[i - 1] * ti[i-1])

        i += 1
        tmp = a
        a = b
        b = tmp % b
        if b == 0:
            break

    headers = ["i", "r_i", "q_i", "s_i", "t_i"]
    table_data = {"i": rounds, "r_i": ri, "q_i": qi, "s_i": si, "t_i": ti}
    return tabulate(table_data, headers=headers)


def main():
    a = 26513
    b = 32321

    print(f"The extended Euclidean algorithm table for a={a} and b={b} is:")
    print(extended_euclidean_algorithm(a, b))

if __name__ == "__main__":
    main()

Modular Arithmetic 1

"Calculate the following integers:

11 ≡ x mod 6

8146798528947 ≡ y mod 17

The solution is the smaller of the two integers."

The first one is easy. 11 mod 6 = 5

The second one is not something to be calculated without help. So lets write a script to help us.

#!/usr/bin/env python3
print(min(11 % 6, 8146798528947 % 17))

Modular Arithmetic 2

"A finite field Fp is the set of integers {0,1,...,p-1}, and under both addition and multiplication there is an inverse element b for every element a in the set, such that

a + b = 0 and a * b = 1.

Lets say we pick p = 17. Calculate 317 mod 17. Now do the same but with 517 mod 17. What would you expect to get for 716 mod 17? Try calculating that. This interesting fact is known as Fermat's little theorem. We'll be needing this (and its generalisations) when we look at RSA cryptography. Now take the prime p = 65537. Calculate 27324678765465536 mod 65537. Did you need a calculator?"

Fermat's little theorem states that if the exponent is p - 1 then x is 1.

So here we simply get 1.

Modular Inverting

"As we've seen, we can work within a finite field Fp, adding and multiplying elements, and always obtain another element of the field. For all elements g in the field, there exists a unique integer d such that g * d ≡ 1 mod p. This is the multiplicative inverse of g. Example: 7 * 8 = 56 ≡ 1 mod 11 What is the inverse element: 3 * d ≡ 1 mod 13?"

With Fermat's little theorem

We know that:
a^(p-1) ≡ 1 mod p
Therefore:
a^(p-1) * a^(-1) ≡ a^(-1) mod p
a^(p-2) * a * a^(-1) ≡ a^(-1) mod p
a^(p-2) ≡ a^(-1) mod p 
<=>
a^(p-2) % p = a^(-1)
#!/usr/bin/env python3
a = 3
p = 13
print(pow(a,p-2) % p)

Last updated