/// <summary>
        /// Creates a new GF2nField of degree <c>i</c> and uses the given <c>G</c> as field polynomial. 
        /// <para>The <c>G</c> is checked whether it is irreducible. This can take some time if <c>Degree</c> is huge!</para>
        /// </summary>
        /// 
        /// <param name="Degree">The degree of the GF2nField</param>
        /// <param name="G">The field polynomial to use</param>
        public GF2nPolynomialField(int Degree, GF2Polynomial G)
        {
            if (Degree < 3)
                throw new ArgumentException("degree must be at least 3");
            if (G.Length != Degree + 1)
                throw new Exception();
            if (!G.IsIrreducible())
                throw new Exception();

            DegreeN = Degree;
            // fieldPolynomial = new Bitstring(polynomial);
            FieldPoly = G;
            ComputeSquaringMatrix();
            int k = 2; // check if the polynomial is a trinomial or pentanomial
            for (int j = 1; j < FieldPoly.Length - 1; j++)
            {
                if (FieldPoly.TestBit(j))
                {
                    k++;
                    if (k == 3)
                        _tc = j;
                    if (k <= 5)
                        _pc[k - 3] = j;
                }
            }
            if (k == 3)
                _isTrinomial = true;
            if (k == 5)
                _isPentanomial = true;

            Fields = new ArrayList();
            Matrices = new ArrayList();
        }
        /// <summary>
        /// Tests random polynomials of degree (n+1) until an irreducible is found and stores the result in <c>field polynomial</c>.
        /// This can take very long for huge degrees.
        /// </summary>
        /// 
        /// <returns>Returns true</returns>
        private bool TestRandom()
        {
            int l;
            bool done = false;

            FieldPoly = new GF2Polynomial(DegreeN + 1);
            l = 0;

            while (!done)
            {
                l++;
                FieldPoly.Randomize();
                FieldPoly.SetBit(DegreeN);
                FieldPoly.SetBit(0);
                if (FieldPoly.IsIrreducible())
                {
                    done = true;
                    return done;
                }
            }

            return done;
        }
        /// <summary>
        /// Tests all trinomials of degree (n+1) until a irreducible is found and stores the result in <c>field polynomial</c>.
        /// Returns false if no irreducible trinomial exists in GF(2^n). This can take very long for huge degrees.
        /// </summary>
        /// 
        /// <returns>Returns true if an irreducible trinomial is found</returns>
        private bool TestTrinomials()
        {
            int i, l;
            bool done = false;
            l = 0;

            FieldPoly = new GF2Polynomial(DegreeN + 1);
            FieldPoly.SetBit(0);
            FieldPoly.SetBit(DegreeN);
            for (i = 1; (i < DegreeN) && !done; i++)
            {
                FieldPoly.SetBit(i);
                done = FieldPoly.IsIrreducible();
                l++;
                if (done)
                {
                    _isTrinomial = true;
                    _tc = i;
                    return done;
                }
                FieldPoly.ResetBit(i);
                done = FieldPoly.IsIrreducible();
            }

            return done;
        }
        /// <summary>
        /// Tests all pentanomials of degree (n+1) until a irreducible is found and stores the result in <c>field polynomial</c>.
        /// Returns false if no irreducible pentanomial exists in GF(2^n).
        /// This can take very long for huge degrees.
        /// </summary>
        /// 
        /// <returns>Returns true if an irreducible pentanomial is found</returns>
        private bool TestPentanomials()
        {
            int i, j, k, l;
            bool done = false;
            l = 0;

            FieldPoly = new GF2Polynomial(DegreeN + 1);
            FieldPoly.SetBit(0);
            FieldPoly.SetBit(DegreeN);

            for (i = 1; (i <= (DegreeN - 3)) && !done; i++)
            {
                FieldPoly.SetBit(i);
                for (j = i + 1; (j <= (DegreeN - 2)) && !done; j++)
                {
                    FieldPoly.SetBit(j);
                    for (k = j + 1; (k <= (DegreeN - 1)) && !done; k++)
                    {
                        FieldPoly.SetBit(k);
                        if (((DegreeN & 1) != 0) | ((i & 1) != 0) | ((j & 1) != 0)
                            | ((k & 1) != 0))
                        {
                            done = FieldPoly.IsIrreducible();
                            l++;
                            if (done)
                            {
                                _isPentanomial = true;
                                _pc[0] = i;
                                _pc[1] = j;
                                _pc[2] = k;
                                return done;
                            }
                        }
                        FieldPoly.ResetBit(k);
                    }
                    FieldPoly.ResetBit(j);
                }
                FieldPoly.ResetBit(i);
            }

            return done;
        }