/// <summary>
 /// Creates a new GF2nPolynomialElement using the given field <c>Gf</c> and int[] <c>Is</c> as value
 /// </summary>
 /// 
 /// <param name="Gf">The GF2nField to use</param>
 /// <param name="Is">The integer string to assign to this GF2nPolynomialElement</param>
 public GF2nPolynomialElement(GF2nPolynomialField Gf, int[] Is)
 {
     mField = Gf;
     mDegree = mField.Degree;
     polynomial = new GF2Polynomial(mDegree, Is);
     polynomial.ExpandN(Gf.Degree);
 }
        /// <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>
 /// Creates a new GF2nPolynomialElement using the given field <c>f</c> and byte[] <c>os</c> as value. 
 /// <para>The conversion is done according to 1363.</para>
 /// </summary>
 /// 
 /// <param name="Gf">The GF2nField to use</param>
 /// <param name="Os">The octet string to assign to this GF2nPolynomialElement</param>
 public GF2nPolynomialElement(GF2nPolynomialField Gf, byte[] Os)
 {
     mField = Gf;
     mDegree = mField.Degree;
     polynomial = new GF2Polynomial(mDegree, Os);
     polynomial.ExpandN(mDegree);
 }
Exemplo n.º 4
0
        /// <summary>
        /// Creates a new PolynomialGF2n from the given Bitstring <c>G</c> over the GF2nField <c>B1</c>
        /// </summary>
        /// 
        /// <param name="G">The Bitstring to use</param>
        /// <param name="B1">The field</param>
        public GF2nPolynomial(GF2Polynomial G, GF2nField B1)
        {
            _size = B1.Degree + 1;
            _coeff = new GF2nElement[_size];
            int i;

            if (B1 is GF2nONBField)
            {
                for (i = 0; i < _size; i++)
                {
                    if (G.TestBit(i))
                        _coeff[i] = GF2nONBElement.One((GF2nONBField)B1);
                    else
                        _coeff[i] = GF2nONBElement.Zero((GF2nONBField)B1);
                }
            }
            else if (B1 is GF2nPolynomialField)
            {
                for (i = 0; i < _size; i++)
                {
                    if (G.TestBit(i))
                        _coeff[i] = GF2nPolynomialElement.One((GF2nPolynomialField)B1);
                    else
                        _coeff[i] = GF2nPolynomialElement.Zero((GF2nPolynomialField)B1);
                }
            }
            else
            {
                throw new ArgumentException("GF2nPolynomial: PolynomialGF2n(Bitstring, GF2nField): B1 must be an instance of GF2nONBField or GF2nPolynomialField!");
            }
        }
 /// <summary>
 /// Create a new random GF2nPolynomialElement using the given field and source of randomness
 /// </summary>
 /// 
 /// <param name="Gf">The GF2nField to use</param>
 /// <param name="Rnd">The source of randomness</param>
 public GF2nPolynomialElement(GF2nPolynomialField Gf, Random Rnd)
 {
     mField = Gf;
     mDegree = mField.Degree;
     polynomial = new GF2Polynomial(mDegree);
     Randomize(Rnd);
 }
 /// <summary>
 /// Creates a new GF2nPolynomialElement using the given field and Bitstring
 /// </summary>
 /// 
 /// <param name="Gf">The GF2nPolynomialField to use</param>
 /// <param name="Gp">The desired value as Bitstring</param>
 public GF2nPolynomialElement(GF2nPolynomialField Gf, GF2Polynomial Gp)
 {
     mField = Gf;
     mDegree = mField.Degree;
     polynomial = new GF2Polynomial(Gp);
     polynomial.ExpandN(mDegree);
 }
Exemplo n.º 7
0
        /// <summary>
        /// Computes the change-of-basis matrix for basis conversion according to 1363.
        /// The result is stored in the lists fields and matrices.
        /// </summary>
        /// 
        /// <param name="B1">The GF2nField to convert to</param>
        public override void ComputeCOBMatrix(GF2nField B1)
        {
            // we are in B0 here!
            if (DegreeN != B1.Degree)
                throw new ArgumentException("GF2nField.computeCOBMatrix: B1 has a different degree and thus cannot be coverted to!");

            int i, j;
            GF2nElement[] gamma;
            GF2nElement u;
            GF2Polynomial[] COBMatrix = new GF2Polynomial[DegreeN];
            for (i = 0; i < DegreeN; i++)
                COBMatrix[i] = new GF2Polynomial(DegreeN);

            // find Random Root
            do
            {
                // u is in representation according to B1
                u = B1.RandomRoot(FieldPoly);
            }
            while (u.IsZero());

            gamma = new GF2nPolynomialElement[DegreeN];
            // build gamma matrix by squaring
            gamma[0] = (GF2nElement)u.Clone();
            for (i = 1; i < DegreeN; i++)
                gamma[i] = gamma[i - 1].Square();

            // convert horizontal gamma matrix by vertical Bitstrings
            for (i = 0; i < DegreeN; i++)
            {
                for (j = 0; j < DegreeN; j++)
                {
                    if (gamma[i].TestBit(j))
                        COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1);
                }
            }

            Fields.Add(B1);
            Matrices.Add(COBMatrix);
            B1.Fields.Add(this);
            B1.Matrices.Add(InvertMatrix(COBMatrix));
        }
Exemplo n.º 8
0
 /// <summary>
 /// Computes the field polynomial for a ONB according to IEEE 1363 A.7.2
 /// </summary>
 protected override void ComputeFieldPolynomial()
 {
     if (_mType == 1)
     {
         FieldPoly = new GF2Polynomial(DegreeN + 1, "ALL");
     }
     else if (_mType == 2)
     {
         // 1. q = 1
         GF2Polynomial q = new GF2Polynomial(DegreeN + 1, "ONE");
         // 2. p = t+1
         GF2Polynomial p = new GF2Polynomial(DegreeN + 1, "X");
         p.AddToThis(q);
         GF2Polynomial r;
         int i;
         // 3. for i = 1 to (m-1) do
         for (i = 1; i < DegreeN; i++)
         {
             // r <- q
             r = q;
             // q <- p
             q = p;
             // p = tq+r
             p = q.ShiftLeft();
             p.AddToThis(r);
         }
         FieldPoly = p;
     }
 }
 /**
  * .
  *
  * @param other t
  */
 /// <summary>
 /// Creates a new GF2nPolynomialElement by cloning the given GF2nPolynomialElement <c>Ge</c>
 /// </summary>
 /// 
 /// <param name="Ge">The GF2nPolynomialElement to clone</param>
 public GF2nPolynomialElement(GF2nPolynomialElement Ge)
 {
     mField = Ge.mField;
     mDegree = Ge.mDegree;
     polynomial = new GF2Polynomial(Ge.polynomial);
 }
Exemplo n.º 10
0
        /// <summary>
        /// Returns the remainder of <c>this</c> divided by <c>G</c> in a new GF2Polynomial
        /// </summary>
        /// 
        /// <param name="G">A GF2Polynomial != 0</param>
        /// 
        /// <returns>Returns a new GF2Polynomial (<c>this</c> % <c>G</c>)</returns>
        public GF2Polynomial Remainder(GF2Polynomial G)
        {
            // a div b = q / r
            GF2Polynomial a = new GF2Polynomial(this);
            GF2Polynomial b = new GF2Polynomial(G);
            GF2Polynomial j;
            int i;

            if (b.IsZero())
                throw new Exception();

            a.ReduceN();
            b.ReduceN();

            if (a._length < b._length)
                return a;

            i = a._length - b._length;
            while (i >= 0)
            {
                j = b.ShiftLeft(i);
                a.SubtractFromThis(j);
                a.ReduceN();
                i = a._length - b._length;
            }

            return a;
        }
Exemplo n.º 11
0
        /// <summary>
        /// Returns this GF2Polynomial shift-left by <c>K</c> in a new GF2Polynomial
        /// </summary>
        /// 
        /// <param name="K">The shift value</param>
        /// 
        /// <returns>Returns a new GF2Polynomial (this &lt;&lt; <c>K</c>)</returns>
        public GF2Polynomial ShiftLeft(int K)
        {
            // Variant 2, requiring a modified shiftBlocksLeft(k)
            // In case of modification, consider a rename to DoShiftBlocksLeft()
            // with an explicit note that this method assumes that the polynomial
            // has already been resized. Or consider doing things inline.
            // Construct the resulting polynomial of appropriate length:
            GF2Polynomial result = new GF2Polynomial(_length + K, _value);
            // Shift left as many multiples of the block size as possible:
            if (K >= 32)
                result.DoShiftBlocksLeft(IntUtils.URShift(K, 5));

            // Shift left by the remaining (<32) amount:
            int remaining = K & 0x1f;
            if (remaining != 0)
            {
                for (int i = result._blocks - 1; i >= 1; i--)
                {
                    result._value[i] <<= remaining;
                    result._value[i] |= IntUtils.URShift(result._value[i - 1], (32 - remaining));
                }
                result._value[0] <<= remaining;
            }

            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);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Converts the given element in representation according to this field to a new element in 
        /// representation according to B1 using the change-of-basis matrix calculated by computeCOBMatrix.
        /// </summary>
        /// 
        /// <param name="Elem">The GF2nElement to convert</param>
        /// <param name="Basis">The basis to convert <c>Elem</c> to</param>
        /// 
        /// <returns>Returns <c>Elem</c> converted to a new element representation according to <c>basis</c></returns>
        public GF2nElement Convert(GF2nElement Elem, GF2nField Basis)
        {
            if (Basis == this)
                return (GF2nElement)Elem.Clone();
            if (FieldPoly.Equals(Basis.FieldPoly))
                return (GF2nElement)Elem.Clone();
            if (DegreeN != Basis.DegreeN)
                throw new Exception("GF2nField.Convert: B1 has a different degree and thus cannot be coverted to!");

            int i;
            GF2Polynomial[] COBMatrix;
            i = Fields.IndexOf(Basis);

            if (i == -1)
            {
                ComputeCOBMatrix(Basis);
                i = Fields.IndexOf(Basis);
            }
            COBMatrix = (GF2Polynomial[])Matrices[i];

            GF2nElement elemCopy = (GF2nElement)Elem.Clone();
            if (elemCopy is GF2nONBElement)
                ((GF2nONBElement)elemCopy).ReverseOrder();

            GF2Polynomial bs = new GF2Polynomial(DegreeN, elemCopy.ToFlexiBigInt());
            bs.ExpandN(DegreeN);
            GF2Polynomial result = new GF2Polynomial(DegreeN);
            for (i = 0; i < DegreeN; i++)
            {
                if (bs.VectorMult(COBMatrix[i]))
                    result.SetBit(DegreeN - 1 - i);
            }

            if (Basis is GF2nPolynomialField)
            {
                return new GF2nPolynomialElement((GF2nPolynomialField)Basis, result);
            }
            else if (Basis is GF2nONBField)
            {
                GF2nONBElement res = new GF2nONBElement((GF2nONBField)Basis, result.ToFlexiBigInt());
                res.ReverseOrder();

                return res;
            }
            else
            {
                throw new Exception("GF2nField.convert: B1 must be an instance of GF2nPolynomialField or GF2nONBField!");
            }
        }
        /// <summary>
        /// Compute <c>this * factor</c> (overwrite <c>this</c>).
        /// </summary>
        /// 
        /// <param name="Factor">The factor</param>
        public override void MultiplyThisBy(IGFElement Factor)
        {
            if (!(Factor is GF2nPolynomialElement))
                throw new Exception();
            if (!mField.Equals(((GF2nPolynomialElement)Factor).mField))
                throw new Exception();
            if (Equals(Factor))
            {
                SquareThis();
                return;
            }

            polynomial = polynomial.Multiply(((GF2nPolynomialElement)Factor).polynomial);
            ReduceThis();
        }
        /// <summary>
        /// Calculates the multiplicative inverse of <c>this</c> using the modified almost inverse algorithm and returns the result in a new GF2nPolynomialElement
        /// </summary>
        /// 
        /// <returns>Returns <c>this</c>^(-1)</returns>
        public GF2nPolynomialElement InvertMAIA()
        {
            if (IsZero())
            {
                throw new ArithmeticException();
            }
            GF2Polynomial b = new GF2Polynomial(mDegree, "ONE");
            GF2Polynomial c = new GF2Polynomial(mDegree);
            GF2Polynomial u = GetGF2Polynomial();
            GF2Polynomial v = mField.FieldPolynomial;
            GF2Polynomial h;
            while (true)
            {
                while (!u.TestBit(0))
                { // x|u (x divides u)
                    u.ShiftRightThis(); // u = u / x
                    if (!b.TestBit(0))
                    {
                        b.ShiftRightThis();
                    }
                    else
                    {
                        b.AddToThis(mField.FieldPolynomial);
                        b.ShiftRightThis();
                    }
                }

                if (u.IsOne())
                    return new GF2nPolynomialElement((GF2nPolynomialField)mField, b);

                u.ReduceN();
                v.ReduceN();

                if (u.Length < v.Length)
                {
                    h = u;
                    u = v;
                    v = h;
                    h = b;
                    b = c;
                    c = h;
                }

                u.AddToThis(v);
                b.AddToThis(c);
            }
        }
        /// <summary>
        /// Calculates the multiplicative inverse of <c>this</c> and returns the result in a new GF2nPolynomialElement
        /// </summary>
        /// 
        /// <returns>Returns <c>this</c>^(-1)</returns>
        public GF2nPolynomialElement InvertEEA()
        {
            if (IsZero())
                throw new ArithmeticException();

            GF2Polynomial b = new GF2Polynomial(mDegree + 32, "ONE");
            b.ReduceN();
            GF2Polynomial c = new GF2Polynomial(mDegree + 32);
            c.ReduceN();
            GF2Polynomial u = GetGF2Polynomial();
            GF2Polynomial v = mField.FieldPolynomial;
            GF2Polynomial h;
            int j;
            u.ReduceN();

            while (!u.IsOne())
            {
                u.ReduceN();
                v.ReduceN();
                j = u.Length - v.Length;
                if (j < 0)
                {
                    h = u;
                    u = v;
                    v = h;
                    h = b;
                    b = c;
                    c = h;
                    j = -j;
                    c.ReduceN(); // this increases the performance
                }

                u.ShiftLeftAddThis(v, j);
                b.ShiftLeftAddThis(c, j);
            }
            b.ReduceN();

            return new GF2nPolynomialElement((GF2nPolynomialField)mField, b);
        }
 /// <summary>
 /// Create the zero element
 /// </summary>
 /// 
 /// <param name="Gf">The finite field</param>
 /// 
 /// <returns>The zero element in the given finite field</returns>
 public static GF2nPolynomialElement Zero(GF2nPolynomialField Gf)
 {
     GF2Polynomial polynomial = new GF2Polynomial(Gf.Degree);
     return new GF2nPolynomialElement(Gf, polynomial);
 }
 /// <summary>
 /// Create the one element
 /// </summary>
 /// 
 /// <param name="Gf">The finite field</param>
 /// 
 /// <returns>The one element in the given finite field</returns>
 public static GF2nPolynomialElement One(GF2nPolynomialField Gf)
 {
     GF2Polynomial polynomial = new GF2Polynomial(Gf.Degree, new int[] { 1 });
     return new GF2nPolynomialElement(Gf, polynomial);
 }
Exemplo n.º 19
0
 /// <summary>
 /// Computes a random root from the given irreducible fieldpolynomial according to IEEE 1363 algorithm A.5.6.
 /// <para>This calculation take very long for big degrees.</para>
 /// </summary>
 /// 
 /// <param name="B0FieldPolynomial">The fieldpolynomial if the other basis as a Bitstring</param>
 /// 
 /// <returns>Returns a random root of BOFieldPolynomial in representation according to this field</returns>
 public abstract GF2nElement RandomRoot(GF2Polynomial B0FieldPolynomial);
 /// <summary>
 /// Squares this GF2nPolynomialElement using GF2nFields squaring matrix. 
 /// <para>This is supposed to be fast when using a polynomial (no tri- or pentanomial) as fieldpolynomial.
 /// Use SquarePreCalc when using a tri- or pentanomial as fieldpolynomial instead.</para>
 /// </summary>
 public void SquareThisMatrix()
 {
     GF2Polynomial result = new GF2Polynomial(mDegree);
     for (int i = 0; i < mDegree; i++)
     {
         if (polynomial.VectorMult(((GF2nPolynomialField)mField).SquaringMatrix[mDegree - i - 1]))
             result.SetBit(i);
     }
     polynomial = result;
 }
Exemplo n.º 21
0
        /// <summary>
        /// Inverts the given matrix represented as bitstrings
        /// </summary>
        /// 
        /// <param name="MatrixN">The matrix to invert as a Bitstring[]</param>
        /// 
        /// <returns>Returns <c>matrix^(-1)</c></returns>
        protected GF2Polynomial[] InvertMatrix(GF2Polynomial[] MatrixN)
        {
            GF2Polynomial[] a = new GF2Polynomial[MatrixN.Length];
            GF2Polynomial[] inv = new GF2Polynomial[MatrixN.Length];
            GF2Polynomial dummy;
            int i, j;
            // initialize a as a copy of matrix and inv as E(inheitsmatrix)
            for (i = 0; i < DegreeN; i++)
            {
                try
                {
                    a[i] = new GF2Polynomial(MatrixN[i]);
                    inv[i] = new GF2Polynomial(DegreeN);
                    inv[i].SetBit(DegreeN - 1 - i);
                }
                catch
                {
                    throw;
                }
            }
            // construct triangle matrix so that for each a[i] the first i bits are
            // zero
            for (i = 0; i < DegreeN - 1; i++)
            {
                // find column where bit i is set
                j = i;
                while ((j < DegreeN) && !a[j].TestBit(DegreeN - 1 - i))
                    j++;

                if (j >= DegreeN)
                    throw new Exception("GF2nField.InvertMatrix: Matrix cannot be inverted!");

                if (i != j)
                { // swap a[i]/a[j] and inv[i]/inv[j]
                    dummy = a[i];
                    a[i] = a[j];
                    a[j] = dummy;
                    dummy = inv[i];
                    inv[i] = inv[j];
                    inv[j] = dummy;
                }

                for (j = i + 1; j < DegreeN; j++)
                { // add column i to all columns>i
                    // having their i-th bit set
                    if (a[j].TestBit(DegreeN - 1 - i))
                    {
                        a[j].AddToThis(a[i]);
                        inv[j].AddToThis(inv[i]);
                    }
                }
            }
            // construct Einheitsmatrix from a
            for (i = DegreeN - 1; i > 0; i--)
            {
                for (j = i - 1; j >= 0; j--)
                { // eliminate the i-th bit in all
                    // columns < i
                    if (a[j].TestBit(DegreeN - 1 - i))
                    {
                        a[j].AddToThis(a[i]);
                        inv[j].AddToThis(inv[i]);
                    }
                }
            }

            return inv;
        }
        /// <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;
        }
        /// <summary>
        /// Computes the change-of-basis matrix for basis conversion according to 1363.
        /// The result is stored in the lists fields and matrices.
        /// </summary>
        /// 
        /// <param name="B1">The GF2nField to convert to</param>
        public override void ComputeCOBMatrix(GF2nField B1)
        {
            // we are in B0 here!
            if (DegreeN != B1.Degree)
                throw new ArgumentException("GF2nPolynomialField.computeCOBMatrix: B1 has a different degree and thus cannot be coverted to!");

            if (B1 is GF2nONBField)
            {
                // speedup (calculation is done in PolynomialElements instead of ONB)
                B1.ComputeCOBMatrix(this);
                return;
            }

            int i, j;
            GF2nElement[] gamma;
            GF2nElement u;
            GF2Polynomial[] COBMatrix = new GF2Polynomial[DegreeN];

            for (i = 0; i < DegreeN; i++)
                COBMatrix[i] = new GF2Polynomial(DegreeN);

            // find Random Root
            do
            {
                // u is in representation according to B1
                u = B1.RandomRoot(FieldPoly);
            }
            while (u.IsZero());

            // build gamma matrix by multiplying by u
            if (u is GF2nONBElement)
            {
                gamma = new GF2nONBElement[DegreeN];
                gamma[DegreeN - 1] = GF2nONBElement.One((GF2nONBField)B1);
            }
            else
            {
                gamma = new GF2nPolynomialElement[DegreeN];
                gamma[DegreeN - 1] = GF2nPolynomialElement.One((GF2nPolynomialField)B1);
            }
            gamma[DegreeN - 2] = u;
            for (i = DegreeN - 3; i >= 0; i--)
                gamma[i] = (GF2nElement)gamma[i + 1].Multiply(u);

            if (B1 is GF2nONBField)
            {
                // convert horizontal gamma matrix by vertical Bitstrings
                for (i = 0; i < DegreeN; i++)
                {
                    for (j = 0; j < DegreeN; j++)
                    {
                        // TODO remember: ONB treats its Bits in reverse order !!!
                        if (gamma[i].TestBit(DegreeN - j - 1))
                            COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1);
                    }
                }
            }
            else
            {
                // convert horizontal gamma matrix by vertical Bitstrings
                for (i = 0; i < DegreeN; i++)
                {
                    for (j = 0; j < DegreeN; j++)
                    {
                        if (gamma[i].TestBit(j))
                            COBMatrix[DegreeN - j - 1].SetBit(DegreeN - i - 1);
                    }
                }
            }

            // store field and matrix for further use
            Fields.Add(B1);
            Matrices.Add(COBMatrix);
            // store field and inverse matrix for further use in B1
            B1.Fields.Add(this);
            B1.Matrices.Add(InvertMatrix(COBMatrix));
        }
        /// <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>
        /// Computes a new squaring matrix used for fast squaring
        /// </summary>
        private void ComputeSquaringMatrix()
        {
            GF2Polynomial[] d = new GF2Polynomial[DegreeN - 1];
            int i, j;
            _squaringMatrix = new GF2Polynomial[DegreeN];

            for (i = 0; i < _squaringMatrix.Length; i++)
                _squaringMatrix[i] = new GF2Polynomial(DegreeN, "ZERO");

            for (i = 0; i < DegreeN - 1; i++)
                d[i] = new GF2Polynomial(1, "ONE").ShiftLeft(DegreeN + i).Remainder(FieldPoly);

            for (i = 1; i <= Math.Abs(DegreeN >> 1); i++)
            {
                for (j = 1; j <= DegreeN; j++)
                {
                    if (d[DegreeN - (i << 1)].TestBit(DegreeN - j))
                        _squaringMatrix[j - 1].SetBit(DegreeN - i);
                }
            }

            for (i = Math.Abs(DegreeN >> 1) + 1; i <= DegreeN; i++)
                _squaringMatrix[(i << 1) - DegreeN - 1].SetBit(DegreeN - i);
        }
Exemplo n.º 26
0
        /// <summary>
        /// Returns this GF2Polynomial shift-left by 1 in a new GF2Polynomial
        /// </summary>
        /// 
        /// <returns>Returns a new GF2Polynomial (this &lt;&lt; 1)</returns>
        public GF2Polynomial ShiftLeft()
        {
            GF2Polynomial result = new GF2Polynomial(_length + 1, _value);

            for (int i = result._blocks - 1; i >= 1; i--)
            {
                result._value[i] <<= 1;
                result._value[i] |= IntUtils.URShift(result._value[i - 1], 31);
            }
            result._value[0] <<= 1;

            return result;
        }
        /// <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;
        }
Exemplo n.º 28
0
        /// <summary>
        /// Multiplies this GF2Polynomial with <c>B</c> and returns the result in a new GF2Polynomial. This method does not reduce the result in GF(2^N).
        /// This method uses classic multiplication (schoolbook).
        /// </summary>
        /// 
        /// <param name="B">A GF2Polynomial</param>
        /// 
        /// <returns>Returns a new GF2Polynomial (<c>this</c> * <c>B</c>)</returns>
        public GF2Polynomial MultiplyClassic(GF2Polynomial B)
        {
            GF2Polynomial result = new GF2Polynomial(Math.Max(_length, B._length) << 1);
            GF2Polynomial[] m = new GF2Polynomial[32];
            int i, j;
            m[0] = new GF2Polynomial(this);

            for (i = 1; i <= 31; i++)
                m[i] = m[i - 1].ShiftLeft();

            for (i = 0; i < B._blocks; i++)
            {
                for (j = 0; j <= 31; j++)
                {
                    if ((B._value[i] & _bitMask[j]) != 0)
                        result.XorThisBy(m[j]);
                }

                for (j = 0; j <= 31; j++)
                    m[j].ShiftBlocksLeft();
            }

            return result;
        }
        /// <summary>
        /// Reduces this GF2nPolynomialElement modulo the field-polynomial
        /// </summary>
        private void ReduceThis()
        {
            if (polynomial.Length > mDegree)
            { // really reduce ?
                if (((GF2nPolynomialField)mField).IsTrinomial)
                { // fieldpolonomial
                    // is trinomial
                    int tc;
                    try
                    {
                        tc = ((GF2nPolynomialField)mField).Tc;
                    }
                    catch (Exception NATExc)
                    {
                        throw new Exception("GF2nPolynomialElement.Reduce: the field polynomial is not a trinomial!");
                    }
                    // do we have to use slow bitwise reduction ?
                    if (((mDegree - tc) <= 32) || (polynomial.Length > (mDegree << 1)))
                    {
                        ReduceTrinomialBitwise(tc);
                        return;
                    }
                    polynomial.ReduceTrinomial(mDegree, tc);

                    return;
                }
                else if (((GF2nPolynomialField)mField).IsPentanomial) // fieldpolynomial is pentanomial
                {
                    int[] pc;
                    try
                    {
                        pc = ((GF2nPolynomialField)mField).Pc;
                    }
                    catch (Exception NATExc)
                    {
                        throw new Exception("GF2nPolynomialElement.Reduce: the field polynomial is not a pentanomial!");
                    }
                    // do we have to use slow bitwise reduction ?
                    if (((mDegree - pc[2]) <= 32) || (polynomial.Length > (mDegree << 1)))
                    {
                        ReducePentanomialBitwise(pc);
                        return;
                    }
                    polynomial.ReducePentanomial(mDegree, pc);

                    return;
                }
                else
                { // fieldpolynomial is something else
                    polynomial = polynomial.Remainder(mField.FieldPolynomial);
                    polynomial.ExpandN(mDegree);

                    return;
                }
            }

            if (polynomial.Length < mDegree)
                polynomial.ExpandN(mDegree);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Returns the absolute quotient of <c>this</c> divided by <c>G</c> in a new GF2Polynomial
        /// </summary>
        /// 
        /// <param name="G">A GF2Polynomial != 0</param>
        /// 
        /// <returns>Returns a new GF2Polynomial |_ <c>this</c> / <c>G</c></returns>
        public GF2Polynomial Quotient(GF2Polynomial G)
        {
            // a div b = q / r
            GF2Polynomial q = new GF2Polynomial(_length);
            GF2Polynomial a = new GF2Polynomial(this);
            GF2Polynomial b = new GF2Polynomial(G);
            GF2Polynomial j;
            int i;

            if (b.IsZero())
                throw new Exception();

            a.ReduceN();
            b.ReduceN();
            if (a._length < b._length)
                return new GF2Polynomial(0);

            i = a._length - b._length;
            q.ExpandN(i + 1);

            while (i >= 0)
            {
                j = b.ShiftLeft(i);
                a.SubtractFromThis(j);
                a.ReduceN();
                q.XorBit(i);
                i = a._length - b._length;
            }

            return q;
        }