diff --git a/BerlekampAlgorithm.cabal b/BerlekampAlgorithm.cabal
new file mode 100644
--- /dev/null
+++ b/BerlekampAlgorithm.cabal
@@ -0,0 +1,54 @@
+-- Initial BerlekampAlgorithm.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+-- The name of the package.
+name:                BerlekampAlgorithm
+
+-- The package version.  See the Haskell package versioning policy (PVP) 
+-- for standards guiding when and how versions should be incremented.
+-- http://www.haskell.org/haskellwiki/Package_versioning_policy
+-- PVP summary:      +-+------- breaking API changes
+--                   | | +----- non-breaking API additions
+--                   | | | +--- code changes with no API change
+version:             0.1.0.0
+
+-- A short (one-line) description of the package.
+synopsis:            Factorization of polynomials over finite field
+
+-- A longer description of the package.
+-- description:         
+
+-- The license under which the package is released.
+license:             BSD3
+
+-- The file containing the license text.
+license-file:        LICENSE
+
+-- The package author(s).
+author:              Abdelwaheb Miled
+
+-- An email address to which users can send suggestions, bug reports, and 
+-- patches.
+maintainer:          abdelwahebmiled@gmail.com
+
+-- A copyright notice.
+-- copyright:           
+
+category:            Math
+
+build-type:          Simple
+
+-- Constraint on the version of Cabal needed to build this package.
+cabal-version:       >=1.8
+
+
+library
+  -- Modules exported by the library.
+  exposed-modules:     BerlekampAlgorithm
+  
+  -- Modules included in this library but not exported.
+  -- other-modules:       
+  
+  -- Other library packages from which modules are imported.
+  build-depends:       base ==4.6.*, besout ==0.2.*
+  
diff --git a/BerlekampAlgorithm.hs b/BerlekampAlgorithm.hs
new file mode 100644
--- /dev/null
+++ b/BerlekampAlgorithm.hs
@@ -0,0 +1,127 @@
+module BerlekampAlgorithm ( g,frob, pivotPos',lswap,triangulizedModIntegerMat,nullSpaceModIntegerMat,mmultZ,
+matrixBerlTranspose ,derivPolyZ,squareFreePolyZ,irreducibilityTestPolyZ,berlekamp,multPoly) where
+import Data.List
+import Bezout 
+-- |Berlekamp's Factorization Algorithm over Fp[x] : computes the factorization of a monic square-free polynomial P into irreducible factor polynomials over F_{p}[x] , p is a prime number. This method is based on linear algebra over finite field.
+-- | g
+g x = if x == Nothing then (- 1) else (\(Just i)->i) x
+
+-- | pivotPos'
+pivotPos' z x = let y = pivotMin x in 
+		case y of (-1,-1) -> (-1,-1)
+			  _  -> pivotPos z x where 
+				pivotPos _ [[]]  = (-1,-1)
+				pivotPos z x = let y = map (head) x in 
+					let w = (findIndex (/= 0) y) in 
+					let w' = g $! w in 
+					if (w' /= (-1)) then (w',z) else pivotPos (z+1) (map (tail) $ x) where 
+pivotMin x = let y = map (findIndex (/=0)) x in 
+		let w = (findIndex (/= Nothing) y) in 
+		let z = (find (/= Nothing) y) in (g w,h z) where 
+		h x = if x == Nothing then (- 1) else (\(Just (Just i))->i) x
+
+-- | lswap
+lswap i j (xs , ys) = (sswap i j xs , sswap i j ys) where 
+sswap i j xs = if i == j then xs else 
+		take l xs ++ [xs !! u] ++ (take (u-l-1) $ drop (l+1) xs) ++ [xs !! l] ++ drop (u+1) xs
+          where l = if i<j then i else j
+                u = if i>j then i else j
+
+-- | triangulizedModIntegerMat
+--triangulizedModIntegerMat p m: gives the gauss triangular decomposition of an integeral matrix m in Fp.
+-- The result is (r, u) where u is a unimodular matrix, r is an upper-triangular matrix , and u.m = r.
+
+triangulizedModIntegerMat p m = let b = fromIntegral $ length m in hnf' p (m , matI b) where
+hnf' :: Integer ->  ([[Integer]],[[Integer]]) -> ([[Integer]],[[Integer]])
+hnf' p (a,b) =  let (px , py) = pivotPos' 0 a in
+		case (px , py) of (-1,-1) -> (a,b)
+			          _ -> let (u ,v) = lswap 0 px (a,b) in
+				       let (c:cs , d:ds) = gaussZ' p (u,v) in 
+				       let (nu , nv) = hnf' p ( cs , ds) in (c:nu , d:nv) where 
+gaussZ' p (u,v) = let (x,y) = gaussZ p (u,v) in (last x : init x , last y : init y) where 
+gaussZ :: Integer -> ([[Integer]],[[Integer]]) -> ([[Integer]],[[Integer]])
+gaussZ _ ([x], a ) = ([x], a)
+gaussZ p ((x:y:xs), (s:t:ix)) = let beta = fromIntegral $ g (findIndex (/= 0) x) in 
+		let  [a,b] = [x!!beta, y!!beta] in 
+		let d = (b * (inverseMod a p)) in
+		let r = red p d x y in let m = red p d s t in 
+		let (u , v) = gaussZ p ((x:xs) ,(s:ix)) in (r:u, m:v) where 
+		red p d x y = zipWith (\c1 c2 -> mods (c2 - (c1 * d)) p ) x y where 
+matI n = [ [fromIntegral $ fromEnum $ i == j | i <- [1..n]] | j <- [1..n]]
+
+-- | nullSpaceModIntegerMat p m : computes the null space of matrix m in Fp
+nullSpaceModIntegerMat :: Integer -> [[Integer]] -> [[Integer]]
+nullSpaceModIntegerMat p x = let (y,z) = triangulizedModIntegerMat p x in ff (y,z) where
+ff ([],_) = []
+ff (x:xs,y:ys) =  if (nub $! x) == [0] then y : ff (xs,ys) else ff (xs,ys)
+
+
+-- | mmultZ
+-- mmultZ p a b : compute the product of two integer matrices in Fp.
+mmultZ p a b = [ [ let y = sum $ zipWith (*) ar bc in mods y p | bc <- (transpose b)] | ar <- a ]
+
+
+-- | gcdPolyZ
+-- gcdPolyZ p P1 P2 : gives the polynomial gcd of P1 , P2 modulo over Fp[x].
+gcdPolyZ p x y = let u = last $ extendedgcdpoly p x y in let v = head u in 
+			let t = inverseMod v p in mMod (map (* t) u) p
+
+--frob
+-- | Frobenius automorphism : linear map V -> V^p - V , V in Fp[x]/P and Fp[x]/P as vector space over the field Fp.
+
+frob :: Integer -> Integer -> [Integer] -> [Integer]
+frob _ 0 _ = [0]
+frob p k h = let y = prettyFormPoly [[1, p * k],[- 1 , k ],[0,0]] in reverse $! last $! euclideanPolyMod p y h 
+
+
+-- |matrixBerl
+-- matrixBerl p f : is the matrix of the Frobenius endomorphism over the canonical base {1,X,X^2..,X^(p-1)} ,
+-- matrixBerl(i,j) = X^(pj)-X^j mod P.
+matrixBerlTranspose :: Integer -> [Integer] -> [[Integer]]
+matrixBerlTranspose p h = let a = genericLength h - 1 in
+	 [let u = fromIntegral k in let v = frob p u h in shift (a - length v) v | k <- [0 .. a - 1]]
+
+-- derivPolyZ
+-- | derivPolyZ : derivative of polynmial P over Fp[x]
+derivPolyZ :: Integer -> [Integer] -> [Integer]
+derivPolyZ _ [] = []
+derivPolyZ p x = init $ reverse [let y = reverse x in 
+		let j = fromIntegral i in mods (j * (y!!i)) p | i <- [0..length x - 1]]
+
+-- | squareFreePolyZ
+-- squareFreePolyZ p f : gives the euclidean quotient of P and gcd(f,f'). That quotient is a square free polynomial.
+squareFreePolyZ :: Integer -> [Integer] -> [Integer]
+squareFreePolyZ p x = let y = derivPolyZ p x in 
+			let z = trim' $ gcdPolyZ p x y in if z == [1] then x else head $ euclideanPolyMod p x z
+
+
+-- |berlekamp
+-- berlekamp p P: gives a complete factorization of a polynom P of irreducible polynoms over Fp[x].
+berlekamp :: Integer -> [Integer] -> [[Integer]]
+berlekamp p f = let g = squareFreePolyZ p f in 
+	let v = map (trim) $! map (reverse ) $! nullSpaceModIntegerMat p (matrixBerlTranspose p g) in
+	let q = length $! v in 
+	case q of 1 -> [g]
+		  _ -> let (a:b:bs) = phi p g v in 			
+			let c = zipgcdPoly p a b in if length c == q then c else zipgcdPoly p c (head bs) where 
+zipgcdPoly _ [] _  = []
+zipgcdPoly p (x:xs) y = let z = zgcdPoly p x y  in z ++ zipgcdPoly p xs y where
+zgcdPoly _ _ [] = []
+zgcdPoly p x (y:ys) = let u = gcdPolyZ p x y in if length u > 1 then u:zgcdPoly p x ys else zgcdPoly p x ys where
+phi _ _ [] = []
+phi p x (v:vs) = let u = filter (\x -> length x > 1) $! [gcdPolyZ p x ((+:) (-) v [i]) | i <- [0 .. p - 1] ] in u : phi p x vs
+
+-- | irreducibilityTestPolyZ
+-- irreducibilityTestPolyZ : irreducibility test of polynomials over Fp[x]
+irreducibilityTestPolyZ :: Integer -> [Integer] -> Bool
+irreducibilityTestPolyZ p f = let g = squareFreePolyZ p f in if g /= f then False else let u = matrixBerlTranspose p g in
+	let v = nullSpaceModIntegerMat p u in
+	let q = length $ v in 
+	case q of 1 -> True
+		  _ -> False 
+-- | multPoly
+-- multPoly : product of polynomials P1, .., Pk in Fp[x].
+multPoly p x = head $! multPoly' p x where
+multPoly' :: Integer ->[[Integer]]-> [[Integer]] 
+multPoly' _ [x] = [x]
+multPoly' p (x:t:xs) = let y = multPolyZ p x t in multPoly' p (y:xs)
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013, Abdelwaheb Miled
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Abdelwaheb Miled nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
