This is a semester project done in Autumn 2017 At Laboratory for Cryptologic Algorithms, EPFL
The goal of the project was to implement a simple Python library for finite field arithmetic which only depends on standard Python libraries.
The Schoof Library was taken as base of the project and algorithms were implemented on top of it. We first began the project from scratch and implemented some classes but finally chose to work with this library. The generic type system used in this library and the presence of all the basic algorithms were the main arguments to use it as base of the project.
On top of the Schoof Library, the following functions were implemented: exponentiation function, primality testing and polynomial factorization.
The Library is composed in three main sections : elliptic curves
, fields
and rings
. There is also a support
folder where we can find useful functions.
Only the classes that were usefull in the project are presented below.
- The
FiniteField
class is a subclass of theField
class and it represents a prime finite field. An object of the class is constructed with a given primep
. All basics operations are implemented, such as addition, multiplication, exponentiation, etc. - The
Polynomials
class is contained inrings
directory. An object of the class is constructed with a given coefficient field (i.e.FiniteField
object). A polynomial can then be constructed by simply passing a list of coefficients. All basics operations are implemented, such as addition, multiplication, exponentiation, etc. - The
primes
file is located insupport
, and it is composed of auxiliary functions for computations related to prime numbers.
As its name suggests, this algorithm is based on the Euclidean Algorithm. Given two integers, the Euclidean Algorithm finds their greatest common divisor.
To find
EUCLIDEAN_ALGORITHM(a, b)
INPUT: two integers a and b
OUTPUT: an integer u such as u = gcd(a,b)
1. IF b = 0, return a
ELSE return EUCLIDEAN_ALGORITHM(b, a mod b)
Given two integers
EXTENDED_EUCLIDEAN_ALGORITHM(u,v)
INPUT: two integers u and v
OUTPUT: (u1, u2, u3) such as u*u1 + v*u2 = u3 = gcd(u, v)
1. SET (u1, u2, u3) = (1, 0, u), (v1, v2, v3) = (0, 1, v)
2. IF v3 = 3, the algorithm terminates
3. SET q = floor(u3/v3) AND THEN SET
(t1, t2, t3) = (u1, u2, u3) - (v1, v2, v3) * q
(u1, u2, u3) = (v1, v2, v3)
(v1, v2, v3) = (t1, t2, t3)
RETURN TO STEP 2
Knowing that
A naive method to compute
The Square-and-Multiply methods is implemented for this goal. It works with the bit representation of the input exponent
First initialize
Set
The first bit
Set $result = result^2 \ (= a^2)$.
The second bit $b_2=0$ so there is nothing more to do.
Set $result = result^2 \ (= a^4)$.
The third bit $b_3=1$ so we set $result = resulta \ (= a^5)$. \
POWER(a, n)
INPUT: two numbers a and n, n is a positive integer
OUTPUT: a^n
1. SET result = a, i = most significant bit of n
2. result = result * result
3. IF i = 1, result = result * a
4. IF i is the last bit of n, the algorithm terminates
ELSE i = next bit, RETURN TO STEP 2
Knowing that we are working in finite fields, primes take an essential role in the project. Primality testing can therefore very useful to unsure the numbers we are working with are prime.
The most naive primality test is trial division. Given an integer
This method has a far to big complexity:
This test is based on the following claim:
Let's assume a prime
To determine the primality of any integer
\newpage
The following table gives values of
1 | 2047 |
2 | 1373653 |
3 | 25326001 |
4 | 3215031751 |
5 | 2152302898747 |
6 | 3474749660383 |
7 | 341550071728321 |
The main part of the project was polynomial factorization over prime.
We first define
Given
So, given a polynomial
We can therefore begin the factorization process by decomposing our polynomial into smaller polynomials
DISTINCT_DEGREE_FACTORIZATION(poly)
INPUT: a monic square free polynomial poly
OUTPUT: The set of all pairs (g, d), such that
f has an irreducible factor of degree d and
g is the product of all monic irreducible
factors of f of degree d
1. SET i = 1, S = {}, poly = f
2. g = gcd(f, x^(p^i) - x)
3. if g != 1
1. S = S U (f, degree of f)
2. f = f/g
4. i = i + 1
5. IF degree of f >= 2*i, RETURN TO STEP 2
6. IF degree of f != 1, S = S U (f, degree of f)
7. IF S is empty return {(f, 1)}
ELSE return S
The last step of the process is, given the polynomial
This algorithm takes as input
Knowing that
If we consider that the two last polynomials contain approximately half of these factors. Their degree is indeed about half of the one of
The algorithm takes a random
CANTOR_ZASSENHAUS(f, d)
INPUT: a monic square free polynomial f of degree n = rd,
which has r >= 2 irreducible factors each of degree d
OUTPUT: The set of monic irreducible factors of f of degree d
1. SET factors = {f}
2. CHOOSE h in Fq[x] with deg(h) < n at random
3. SET e = (p^d - 1)/2 AND g = h^e - 1 (mod f)
4. FOR EACH u in factors with deg(u) > d do:
1. IF gcd(g, u) != 1 AND gcd(g, u) != u,
factors = factors \ {u} U {(gcd_temp, u/gcd_temp)}
5. IF size of factors < r, RETURN TO STEP 2
The exponentiation function is often used, optimizing it is gainful for the total runtime of the program.
We also implemented some missing functions. All the project was about working with prime numbers, prime testing was indeed
a must have to handle potential errors.
Finding the inverse of a field element is useful for division, which is an often used operation.
Finally, the polynomial factorization was not present at all in the Schoof Library. This was the main part of the project.
We first implemented irreducibility testing and then a main algorithm to do the factorization.
One of the possible future implementations for this project would be polynomials over finite fields extensions and over rationals.