/// <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>
        /// 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);
        }