#finite-fields #matrix-operations #prime-field #polynomial

galois_field

Library for convenient operations on finite field, polynomials, and matrices over finite field

12 releases

0.1.11 Oct 28, 2022
0.1.10 Oct 28, 2022

#1418 in Math

MIT license

49KB
998 lines

Table of Contents

  1. finite fields
  2. What makes it different from other libraries?
    1. Pros:
    2. Cons:
  3. Usage
  4. Examples
    1. Prime Field
    2. Galois Field
    3. Polynomial over Fp
    4. Polynomial over GF(pn)
    5. Matrix over FiniteField

finite fields

A Rust library for operations on finite field, featuring:

  • Sum, difference, product, and quotient of elements Fp
  • Sum, difference, product, and quotient of elements GF(pn)
  • Obtaining the primitive polynomial
  • Sum, difference, product, quotient, and remainder of polynomial over Fp
  • Sum, difference, product, quotient, and remainder of polynomial over GF(pn)
  • Sum, product of Matrix Fp
  • Sum, product of Matrix GF(pn)
  • The sweep method (or Gaussian elimination) of matrices on finite bodies (Fp, GF(pn)) is also available.

What makes it different from other libraries?

Pros:

  • Can be calculated with Fp, GF(pn) for any prime and any multiplier, not limited to a char 2.
  • Can freely compute six types of element: prime field, Galois field, polynomial of prime field, polynomial of Galois field, matrix of prime field, and matrix of Galois field.
  • Each can be calculated with +-*/, so you can write natural code.
  • Matrix operations on finite field (Fp, GF(pn)) can also be performed.
  • The sweep method can be available.

Cons:

  • It takes longer than other libraries because it is not optimized for each character.

Usage

Add this to your Cargo.toml:

[dependencies]
galois_field = "0.1.11"

Examples

Prime Field

use galois_field::*;

let char: u32 = 5;
let x:FiniteField = FiniteField{
	char: char,
	element:Element::PrimeField{element:0} // 0 in F_5
};
let y:FiniteField = FiniteField{
	char: char,
	element:Element::PrimeField{element:1} // 1 in F_5
};
println!("x + y = {:?}", (x.clone() + y.clone()).element); // ->1
println!("x - y = {:?}", (x.clone() - y.clone()).element); // -> 4
println!("x * y = {:?}", (x.clone() * y.clone()).element); // -> 0
println!("x / y = {:?}", (x.clone() / y.clone()).element); // -> 0

Galois Field

use galois_field::*;

fn main(){
	// consider GF(2^4)
	let char: u32 = 2;
	let n = 4;
	let primitive_polynomial = Polynomial::get_primitive_polynomial(char, n);
	let x:FiniteField = FiniteField{
 		char: char,
 		element:Element::GaloisField{element:vec![0,1],primitive_polynomial:primitive_polynomial.clone()} // i.e. [0,1] = x -> 2 over GF(2^4)
	};
	let y:FiniteField = FiniteField{
 		char: char,
 		element:Element::GaloisField{element:vec![0,0,1,1],primitive_polynomial:primitive_polynomial.clone()} // i.e. [0,0,1,1] = x^3 + x^2 -> 12 over GF(2^4)
	};
	println!("x + y = {:?}", (x.clone() + y.clone()).element);
	println!("x - y = {:?}", (x.clone() - y.clone()).element);
	println!("x * y = {:?}", (x.clone() * y.clone()).element);
	println!("x / y = {:?}", (x.clone() / y.clone()).element);

}

Polynomial over Fp

use galois_field::*;

fn main() {
	// character
    let char: u32 = 2;

	let element0:FiniteField = FiniteField{
		char: char,
		element:Element::PrimeField{element:0} // 0 in F_5
	};
	let element1:FiniteField = FiniteField{
		char: char,
		element:Element::PrimeField{element:1} // 1 in F_5
	};


	let f: Polynomial = Polynomial {
        coef: vec![element1.clone(),element0.clone(),element0.clone(),element0.clone(),element1.clone()]
	};
    let g: Polynomial = Polynomial {
		coef: vec![element1.clone(),element0.clone(),element0.clone(),element1.clone(),element1.clone()]
    };
    println!("f + g = {:?}", (f.clone()+g.clone()).coef);
	println!("f - g = {:?}", (f.clone()-g.clone()).coef);
	println!("f * g = {:?}", (f.clone()*g.clone()).coef);
	println!("f / g = {:?}", (f.clone()/g.clone()).coef);
	println!("f % g = {:?}", (f.clone()%g.clone()).coef);
	
}

Polynomial over GF(pn)

Same as above

Matrix over FiniteField

use galois_field::*;

let char = 3;
let element0: FiniteField = FiniteField {
    char: char,
    element: Element::PrimeField { element: 0 },
};
let element1: FiniteField = FiniteField {
    char: char,
    element: Element::PrimeField { element: 1 },
};
let element2: FiniteField = FiniteField {
    char: char,
    element: Element::PrimeField { element: 2 },
};


let mut matrix_element:Vec<Vec<FiniteField>> = vec![
    vec![element0.clone(),element1.clone(), element0.clone()],
    vec![element2.clone(),element2.clone(), element1.clone()],
    vec![element1.clone(),element0.clone(), element1.clone()]
];
let mut matrix = Matrix{
    element: matrix_element,
};

println!("m+m = {:?}", m.clone()+m.clone());
println!("m*m = {:?}", m.clone()*m.clone());

let mut sweep_matrix = m.sweep_method();
println!("{:?}", sweep_matrix);

No runtime deps