/// <summary>
        /// Multiplies <c>this</c> by <c>P</c> and returns the result in a new PolynomialGF2n
        /// </summary>
        ///
        /// <param name="P">The PolynomialGF2n to multiply</param>
        ///
        /// <returns>Returns <c>this</c> * <c>P</c></returns>
        public GF2nPolynomial Multiply(GF2nPolynomial P)
        {
            int i, j;
            int aDegree = Size;
            int bDegree = P.Size;

            if (aDegree != bDegree)
            {
                throw new ArgumentException("PolynomialGF2n.Multiply: this and b must have the same size!");
            }

            GF2nPolynomial result = new GF2nPolynomial((aDegree << 1) - 1);

            for (i = 0; i < Size; i++)
            {
                for (j = 0; j < P.Size; j++)
                {
                    if (result._coeff[i + j] == null)
                    {
                        result._coeff[i + j] = (GF2nElement)_coeff[i].Multiply(P._coeff[j]);
                    }
                    else
                    {
                        result._coeff[i + j] = (GF2nElement)result._coeff[i + j].Add(_coeff[i].Multiply(P._coeff[j]));
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Divides <c>this</c> by <c>B</c> and stores the quotient in a new PolynomialGF2n
        /// </summary>
        ///
        /// <param name="B">The divisor</param>
        ///
        /// <returns>Returns the quotient <c>this</c> / <c>B</c></returns>
        public GF2nPolynomial Quotient(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            result = Divide(B);

            return(result[0]);
        }
        /// <summary>
        /// Divides <c>this</c> by <c>b</c> and stores the remainder in a new PolynomialGF2n
        /// </summary>
        ///
        /// <param name="B">The divisor</param>
        ///
        /// <returns>Returns The remainder <c>this</c> % <c>b</c></returns>
        public GF2nPolynomial Remainder(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            result = Divide(B);

            return(result[1]);
        }
        /// <summary>
        /// Adds the PolynomialGF2n <c>G</c> to <c>this</c> and returns the result in a new <c>PolynomialGF2n</c>
        /// </summary>
        ///
        /// <param name="P">The <c>PolynomialGF2n</c> to add</param>
        ///
        /// <returns>Returns <c>this + b</c></returns>
        public GF2nPolynomial Add(GF2nPolynomial P)
        {
            GF2nPolynomial result;

            if (Size >= P.Size)
            {
                result = new GF2nPolynomial(Size);
                int i;

                for (i = 0; i < P.Size; i++)
                {
                    result._coeff[i] = (GF2nElement)_coeff[i].Add(P._coeff[i]);
                }
                for (; i < Size; i++)
                {
                    result._coeff[i] = _coeff[i];
                }
            }
            else
            {
                result = new GF2nPolynomial(P.Size);
                int i;

                for (i = 0; i < Size; i++)
                {
                    result._coeff[i] = (GF2nElement)_coeff[i].Add(P._coeff[i]);
                }
                for (; i < P.Size; i++)
                {
                    result._coeff[i] = P._coeff[i];
                }
            }

            return(result);
        }
        /// <summary>
        /// Creates a new PolynomialGF2n by cloning the given PolynomialGF2n <c>G</c>
        /// </summary>
        /// 
        /// <param name="G">The PolynomialGF2n to clone</param>
        public GF2nPolynomial(GF2nPolynomial G)
        {
            int i;
            _coeff = new GF2nElement[G._size];
            _size = G._size;

            for (i = 0; i < _size; i++)
                _coeff[i] = (GF2nElement)G._coeff[i].Clone();
        }
        /// <summary>
        /// Compute a random root of the given GF2Polynomial
        /// </summary>
        ///
        /// <param name="G">The polynomial</param>
        ///
        /// <returns>Returns a random root of <c>G</c></returns>
        public override GF2nElement RandomRoot(GF2Polynomial G)
        {
            // We are in B1!!!
            GF2nPolynomial c;
            GF2nPolynomial ut;
            GF2nElement    u;
            GF2nPolynomial h;
            int            hDegree;
            // 1. Set g(t) <- f(t)
            GF2nPolynomial g       = new GF2nPolynomial(G, this);
            int            gDegree = g.Degree;
            int            i;

            // 2. while deg(g) > 1
            while (gDegree > 1)
            {
                do
                {
                    // 2.1 choose random u (element of) GF(2^m)
                    u  = new GF2nPolynomialElement(this, new Random());
                    ut = new GF2nPolynomial(2, GF2nPolynomialElement.Zero(this));
                    // 2.2 Set c(t) <- ut
                    ut.Set(1, u);
                    c = new GF2nPolynomial(ut);
                    // 2.3 For i from 1 to m-1 do
                    for (i = 1; i <= DegreeN - 1; i++)
                    {
                        // 2.3.1 c(t) <- (c(t)^2 + ut) mod g(t)
                        c = c.MultiplyAndReduce(c, g);
                        c = c.Add(ut);
                    }
                    // 2.4 set h(t) <- GCD(c(t), g(t))
                    h = c.Gcd(g);
                    // 2.5 if h(t) is constant or deg(g) = deg(h) then go to
                    // step 2.1
                    hDegree = h.Degree;
                    gDegree = g.Degree;
                }while ((hDegree == 0) || (hDegree == gDegree));

                // 2.6 If 2deg(h) > deg(g) then set g(t) <- g(t)/h(t) ...
                if ((hDegree << 1) > gDegree)
                {
                    g = g.Quotient(h);
                }
                else
                {
                    g = new GF2nPolynomial(h); // ... else g(t) <- h(t)
                }
                gDegree = g.Degree;
            }

            // 3. Output g(0)
            return(g.At(0));
        }
        /// <summary>
        /// Multiplies the scalar <c>E</c> to each coefficient of this PolynomialGF2n and returns the result in a new PolynomialGF2n
        /// </summary>
        ///
        /// <param name="E">The scalar to multiply</param>
        ///
        /// <returns>Returns <c>this</c> x <c>E</c></returns>
        public GF2nPolynomial ScalarMultiply(GF2nElement E)
        {
            GF2nPolynomial result = new GF2nPolynomial(Size);

            for (int i = 0; i < Size; i++)
            {
                result._coeff[i] = (GF2nElement)_coeff[i].Multiply(E);
            }

            return(result);
        }
        /// <summary>
        /// Creates a new PolynomialGF2n by cloning the given PolynomialGF2n <c>G</c>
        /// </summary>
        ///
        /// <param name="G">The PolynomialGF2n to clone</param>
        public GF2nPolynomial(GF2nPolynomial G)
        {
            int i;

            _coeff = new GF2nElement[G._size];
            _size  = G._size;

            for (i = 0; i < _size; i++)
            {
                _coeff[i] = (GF2nElement)G._coeff[i].Clone();
            }
        }
Exemple #9
0
        /// <summary>
        /// Creates a new PolynomialGF2n by cloning the given PolynomialGF2n <c>G</c>
        /// </summary>
        ///
        /// <param name="G">The PolynomialGF2n to clone</param>
        public GF2nPolynomial(GF2nPolynomial G)
        {
            int i;

            m_coeff = new GF2nElement[G.m_Size];
            m_Size  = G.m_Size;

            for (i = 0; i < m_Size; i++)
            {
                m_coeff[i] = (GF2nElement)G.m_coeff[i].Clone();
            }
        }
Exemple #10
0
        /// <summary>
        /// Shifts left <c>this</c> by <c>N</c> and stores the result in <c>this</c> PolynomialGF2n
        /// </summary>
        ///
        /// <param name="N">The amount the amount to shift the coefficients</param>
        ///
        /// <returns>The shifted polynomial</returns>
        public GF2nPolynomial ShiftLeft(int N)
        {
            if (N <= 0)
            {
                return(new GF2nPolynomial(this));
            }

            GF2nPolynomial result = new GF2nPolynomial(_size + N, _coeff[0]);

            result.AssignZeroToElements();

            for (int i = 0; i < _size; i++)
            {
                result._coeff[i + N] = _coeff[i];
            }

            return(result);
        }
Exemple #11
0
        /// <summary>
        /// Divides <c>this</c> by <c>b</c> and stores the result in a new PolynomialGF2n[2], quotient in result[0] and remainder in result[1]
        /// </summary>
        ///
        /// <param name="B">The divisor</param>
        ///
        /// <returns>Retuens the quotient and remainder of <c>this</c> / <c>b</c></returns>
        public GF2nPolynomial[] Divide(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            GF2nPolynomial   a      = new GF2nPolynomial(this);

            a.Shrink();
            GF2nPolynomial shift;
            GF2nElement    factor;
            int            bDegree = B.Degree;
            GF2nElement    inv     = (GF2nElement)B._coeff[bDegree].Invert();

            if (a.Degree < bDegree)
            {
                result[0] = new GF2nPolynomial(this);
                result[0].AssignZeroToElements();
                result[0].Shrink();
                result[1] = new GF2nPolynomial(this);
                result[1].Shrink();
                return(result);
            }

            result[0] = new GF2nPolynomial(this);
            result[0].AssignZeroToElements();
            int i = a.Degree - bDegree;

            while (i >= 0)
            {
                factor = (GF2nElement)a._coeff[a.Degree].Multiply(inv);
                shift  = B.ScalarMultiply(factor);
                shift.ShiftThisLeft(i);
                a = a.Add(shift);
                a.Shrink();
                result[0]._coeff[i] = (GF2nElement)factor.Clone();
                i = a.Degree - bDegree;
            }

            result[1] = a;
            result[0].Shrink();
            return(result);
        }
Exemple #12
0
        /// <summary>
        /// Computes the greatest common divisor of <c>this</c> and <c>g</c> and returns the result in a new PolynomialGF2n
        /// </summary>
        ///
        /// <param name="G">The GF2nPolynomial</param>
        ///
        /// <returns>Returns gcd(<c>this</c>, <c>g</c>)</returns>
        public GF2nPolynomial Gcd(GF2nPolynomial G)
        {
            GF2nPolynomial a = new GF2nPolynomial(this);
            GF2nPolynomial b = new GF2nPolynomial(G);

            a.Shrink();
            b.Shrink();
            GF2nPolynomial c;
            GF2nPolynomial result;
            GF2nElement    alpha;

            while (!b.IsZero())
            {
                c = a.Remainder(b);
                a = b;
                b = c;
            }

            alpha  = a._coeff[a.Degree];
            result = a.ScalarMultiply((GF2nElement)alpha.Invert());

            return(result);
        }
Exemple #13
0
        /// <summary>
        /// Compare this element with another object
        /// </summary>
        ///
        /// <param name="Obj">The object for comprison</param>
        ///
        /// <returns>Returns <c>true</c> if the two objects are equal, <c>false</c> otherwise</returns>
        public override bool Equals(Object Obj)
        {
            if (Obj == null || !(Obj is GF2nPolynomial))
            {
                return(false);
            }

            GF2nPolynomial otherPol = (GF2nPolynomial)Obj;

            if (Degree != otherPol.Degree)
            {
                return(false);
            }

            for (int i = 0; i < _size; i++)
            {
                if (!_coeff[i].Equals(otherPol._coeff[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
 /// <summary>
 /// Reduces <c>this</c> by <c>G</c> and returns the result in a newPolynomialGF2n
 /// </summary>
 /// 
 /// <param name="G">The modulus</param>
 /// 
 /// <returns>Returns <c>this</c> % <c>G</c></returns>
 public GF2nPolynomial Reduce(GF2nPolynomial G)
 {
     return Remainder(G);
 }
        /// <summary>
        /// Multiplies <c>this</c> by <c>P</c> and returns the result in a new PolynomialGF2n
        /// </summary>
        /// 
        /// <param name="P">The PolynomialGF2n to multiply</param>
        /// 
        /// <returns>Returns <c>this</c> * <c>P</c></returns>
        public GF2nPolynomial Multiply(GF2nPolynomial P)
        {
            int i, j;
            int aDegree = Size;
            int bDegree = P.Size;
            if (aDegree != bDegree)
                throw new ArgumentException("PolynomialGF2n.Multiply: this and b must have the same size!");

            GF2nPolynomial result = new GF2nPolynomial((aDegree << 1) - 1);
            for (i = 0; i < Size; i++)
            {
                for (j = 0; j < P.Size; j++)
                {
                    if (result._coeff[i + j] == null)
                        result._coeff[i + j] = (GF2nElement)_coeff[i].Multiply(P._coeff[j]);
                    else
                        result._coeff[i + j] = (GF2nElement)result._coeff[i + j].Add(_coeff[i].Multiply(P._coeff[j]));
                }
            }

            return result;
        }
        /// <summary>
        /// Divides <c>this</c> by <c>b</c> and stores the result in a new PolynomialGF2n[2], quotient in result[0] and remainder in result[1]
        /// </summary>
        /// 
        /// <param name="B">The divisor</param>
        /// 
        /// <returns>Retuens the quotient and remainder of <c>this</c> / <c>b</c></returns>
        public GF2nPolynomial[] Divide(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            GF2nPolynomial a = new GF2nPolynomial(this);
            a.Shrink();
            GF2nPolynomial shift;
            GF2nElement factor;
            int bDegree = B.Degree;
            GF2nElement inv = (GF2nElement)B._coeff[bDegree].Invert();

            if (a.Degree < bDegree)
            {
                result[0] = new GF2nPolynomial(this);
                result[0].AssignZeroToElements();
                result[0].Shrink();
                result[1] = new GF2nPolynomial(this);
                result[1].Shrink();
                return result;
            }

            result[0] = new GF2nPolynomial(this);
            result[0].AssignZeroToElements();
            int i = a.Degree - bDegree;

            while (i >= 0)
            {
                factor = (GF2nElement)a._coeff[a.Degree].Multiply(inv);
                shift = B.ScalarMultiply(factor);
                shift.ShiftThisLeft(i);
                a = a.Add(shift);
                a.Shrink();
                result[0]._coeff[i] = (GF2nElement)factor.Clone();
                i = a.Degree - bDegree;
            }

            result[1] = a;
            result[0].Shrink();
            return result;
        }
        /// <summary>
        /// Divides <c>this</c> by <c>b</c> and stores the remainder in a new PolynomialGF2n
        /// </summary>
        /// 
        /// <param name="B">The divisor</param>
        /// 
        /// <returns>Returns The remainder <c>this</c> % <c>b</c></returns>
        public GF2nPolynomial Remainder(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            result = Divide(B);

            return result[1];
        }
        /// <summary>
        /// Computes the greatest common divisor of <c>this</c> and <c>g</c> and returns the result in a new PolynomialGF2n
        /// </summary>
        /// 
        /// <param name="G">The GF2nPolynomial</param>
        /// 
        /// <returns>Returns gcd(<c>this</c>, <c>g</c>)</returns>
        public GF2nPolynomial Gcd(GF2nPolynomial G)
        {
            GF2nPolynomial a = new GF2nPolynomial(this);
            GF2nPolynomial b = new GF2nPolynomial(G);
            a.Shrink();
            b.Shrink();
            GF2nPolynomial c;
            GF2nPolynomial result;
            GF2nElement alpha;

            while (!b.IsZero())
            {
                c = a.Remainder(b);
                a = b;
                b = c;
            }

            alpha = a._coeff[a.Degree];
            result = a.ScalarMultiply((GF2nElement)alpha.Invert());

            return result;
        }
Exemple #19
0
 /// <summary>
 /// Reduces <c>this</c> by <c>G</c> and returns the result in a newPolynomialGF2n
 /// </summary>
 ///
 /// <param name="G">The modulus</param>
 ///
 /// <returns>Returns <c>this</c> % <c>G</c></returns>
 public GF2nPolynomial Reduce(GF2nPolynomial G)
 {
     return(Remainder(G));
 }
Exemple #20
0
 /// <summary>
 /// Multiplies <c>this</c> by <c>B</c>, reduces the result by <c>G</c> and returns it in a new PolynomialGF2n
 /// </summary>
 ///
 /// <param name="B">The PolynomialGF2n to multiply</param>
 /// <param name="G">The modulus</param>
 ///
 /// <returns>Returns <c>this</c> * <c>B</c> mod <c>G</c></returns>
 public GF2nPolynomial MultiplyAndReduce(GF2nPolynomial B, GF2nPolynomial G)
 {
     return(Multiply(B).Reduce(G));
 }
 /// <summary>
 /// Multiplies <c>this</c> by <c>B</c>, reduces the result by <c>G</c> and returns it in a new PolynomialGF2n
 /// </summary>
 /// 
 /// <param name="B">The PolynomialGF2n to multiply</param>
 /// <param name="G">The modulus</param>
 /// 
 /// <returns>Returns <c>this</c> * <c>B</c> mod <c>G</c></returns>
 public GF2nPolynomial MultiplyAndReduce(GF2nPolynomial B, GF2nPolynomial G)
 {
     return Multiply(B).Reduce(G);
 }
        /// <summary>
        /// Multiplies the scalar <c>E</c> to each coefficient of this PolynomialGF2n and returns the result in a new PolynomialGF2n
        /// </summary>
        /// 
        /// <param name="E">The scalar to multiply</param>
        /// 
        /// <returns>Returns <c>this</c> x <c>E</c></returns>
        public GF2nPolynomial ScalarMultiply(GF2nElement E)
        {
            GF2nPolynomial result = new GF2nPolynomial(Size);

            for (int i = 0; i < Size; i++)
                result._coeff[i] = (GF2nElement)_coeff[i].Multiply(E);

            return result;
        }
        /// <summary>
        /// Shifts left <c>this</c> by <c>N</c> and stores the result in <c>this</c> PolynomialGF2n
        /// </summary>
        /// 
        /// <param name="N">The amount the amount to shift the coefficients</param>
        /// 
        /// <returns>The shifted polynomial</returns>
        public GF2nPolynomial ShiftLeft(int N)
        {
            if (N <= 0)
                return new GF2nPolynomial(this);

            GF2nPolynomial result = new GF2nPolynomial(_size + N, _coeff[0]);
            result.AssignZeroToElements();

            for (int i = 0; i < _size; i++)
                result._coeff[i + N] = _coeff[i];

            return result;
        }
        /// <summary>
        /// Adds the PolynomialGF2n <c>G</c> to <c>this</c> and returns the result in a new <c>PolynomialGF2n</c>
        /// </summary>
        /// 
        /// <param name="P">The <c>PolynomialGF2n</c> to add</param>
        /// 
        /// <returns>Returns <c>this + b</c></returns>
        public GF2nPolynomial Add(GF2nPolynomial P)
        {
            GF2nPolynomial result;
            if (Size >= P.Size)
            {
                result = new GF2nPolynomial(Size);
                int i;

                for (i = 0; i < P.Size; i++)
                    result._coeff[i] = (GF2nElement)_coeff[i].Add(P._coeff[i]);
                for (; i < Size; i++)
                    result._coeff[i] = _coeff[i];
            }
            else
            {
                result = new GF2nPolynomial(P.Size);
                int i;

                for (i = 0; i < Size; i++)
                    result._coeff[i] = (GF2nElement)_coeff[i].Add(P._coeff[i]);
                for (; i < P.Size; i++)
                    result._coeff[i] = P._coeff[i];
            }

            return result;
        }
        /// <summary>
        /// Compute a random root of the given GF2Polynomial
        /// </summary>
        /// 
        /// <param name="G">The polynomial</param>
        /// 
        /// <returns>Returns a random root of <c>G</c></returns>
        public override GF2nElement RandomRoot(GF2Polynomial G)
        {
            // We are in B1!!!
            GF2nPolynomial c;
            GF2nPolynomial ut;
            GF2nElement u;
            GF2nPolynomial h;
            int hDegree;
            // 1. Set g(t) <- f(t)
            GF2nPolynomial g = new GF2nPolynomial(G, this);
            int gDegree = g.Degree;
            int i;

            // 2. while deg(g) > 1
            while (gDegree > 1)
            {
                do
                {
                    // 2.1 choose random u (element of) GF(2^m)
                    u = new GF2nPolynomialElement(this, new Random());
                    ut = new GF2nPolynomial(2, GF2nPolynomialElement.Zero(this));
                    // 2.2 Set c(t) <- ut
                    ut.Set(1, u);
                    c = new GF2nPolynomial(ut);
                    // 2.3 For i from 1 to m-1 do
                    for (i = 1; i <= DegreeN - 1; i++)
                    {
                        // 2.3.1 c(t) <- (c(t)^2 + ut) mod g(t)
                        c = c.MultiplyAndReduce(c, g);
                        c = c.Add(ut);
                    }
                    // 2.4 set h(t) <- GCD(c(t), g(t))
                    h = c.Gcd(g);
                    // 2.5 if h(t) is constant or deg(g) = deg(h) then go to
                    // step 2.1
                    hDegree = h.Degree;
                    gDegree = g.Degree;
                }
                while ((hDegree == 0) || (hDegree == gDegree));

                // 2.6 If 2deg(h) > deg(g) then set g(t) <- g(t)/h(t) ...
                if ((hDegree << 1) > gDegree)
                    g = g.Quotient(h);
                else
                    g = new GF2nPolynomial(h); // ... else g(t) <- h(t)

                gDegree = g.Degree;
            }

            // 3. Output g(0)
            return g.At(0);
        }
        /// <summary>
        /// Divides <c>this</c> by <c>B</c> and stores the quotient in a new PolynomialGF2n
        /// </summary>
        /// 
        /// <param name="B">The divisor</param>
        /// 
        /// <returns>Returns the quotient <c>this</c> / <c>B</c></returns>
        public GF2nPolynomial Quotient(GF2nPolynomial B)
        {
            GF2nPolynomial[] result = new GF2nPolynomial[2];
            result = Divide(B);

            return result[0];
        }