Beispiel #1
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>
        public void ShiftThisLeft(int N)
        {
            if (N > 0)
            {
                int       i;
                int       oldSize = _size;
                GF2nField f       = _coeff[0].GetField();
                Enlarge(_size + N);

                for (i = oldSize - 1; i >= 0; i--)
                {
                    _coeff[i + N] = _coeff[i];
                }

                if (_coeff[0] is GF2nPolynomialElement)
                {
                    for (i = N - 1; i >= 0; i--)
                    {
                        _coeff[i] = GF2nPolynomialElement.Zero((GF2nPolynomialField)f);
                    }
                }
                else if (_coeff[0] is GF2nONBElement)
                {
                    for (i = N - 1; i >= 0; i--)
                    {
                        _coeff[i] = GF2nONBElement.Zero((GF2nONBField)f);
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Enlarges the size of this PolynomialGF2n to <c>k</c> + 1
        /// </summary>
        ///
        /// <param name="K">The new maximum degree</param>
        public void Enlarge(int K)
        {
            if (K <= _size)
            {
                return;
            }

            int i;

            GF2nElement[] res = new GF2nElement[K];
            Array.Copy(_coeff, 0, res, 0, _size);
            GF2nField f = _coeff[0].GetField();

            if (_coeff[0] is GF2nPolynomialElement)
            {
                for (i = _size; i < K; i++)
                {
                    res[i] = GF2nPolynomialElement.Zero((GF2nPolynomialField)f);
                }
            }
            else if (_coeff[0] is GF2nONBElement)
            {
                for (i = _size; i < K; i++)
                {
                    res[i] = GF2nONBElement.Zero((GF2nONBField)f);
                }
            }

            _size  = K;
            _coeff = res;
        }
Beispiel #3
0
        /// <summary>
        /// Calculates <c>this</c> to the power of <c>K</c> and returns the result in a new GF2nPolynomialElement
        /// </summary>
        ///
        /// <param name="K">The power</param>
        ///
        /// <returns>Returns <c>this</c>^<c>K</c> in a new GF2nPolynomialElement</returns>
        public GF2nPolynomialElement Power(int K)
        {
            if (K == 1)
            {
                return(new GF2nPolynomialElement(this));
            }

            GF2nPolynomialElement result = GF2nPolynomialElement.One((GF2nPolynomialField)mField);

            if (K == 0)
            {
                return(result);
            }

            GF2nPolynomialElement x = new GF2nPolynomialElement(this);

            x.polynomial.ExpandN((x.mDegree << 1) + 32); // increase performance
            x.polynomial.ReduceN();

            for (int i = 0; i < mDegree; i++)
            {
                if ((K & (1 << i)) != 0)
                {
                    result.MultiplyThisBy(x);
                }

                x.Square();
            }

            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Squares this GF2nPolynomialElement by shifting left its Bitstring and reducing.
        /// <para>This is supposed to be the slowest method. Use SquarePreCalc or SquareMatrix instead.</para>
        /// </summary>
        ///
        /// <returns></returns>
        public GF2nPolynomialElement SquareBitwise()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);

            result.SquareThisBitwise();
            result.ReduceThis();
            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// Squares this GF2nPolynomialElement using GF2nField's 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>
        ///
        /// <returns>Returns <c>this^2</c> (newly created)</returns>
        public GF2nPolynomialElement SquareMatrix()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);

            result.SquareThisMatrix();
            result.ReduceThis();
            return(result);
        }
Beispiel #6
0
        /// <summary>
        /// Compute the sum of this element and <c>Addend</c>.
        /// </summary>
        ///
        /// <param name="Addend">The addend</param>
        ///
        /// <returns>Returns <c>this + other</c></returns>
        public override IGFElement Add(IGFElement Addend)
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);

            result.AddToThis(Addend);

            return(result);
        }
Beispiel #7
0
        /// <summary>
        /// Increase the element by one
        /// </summary>
        ///
        /// <returns>Returns <c>this</c> + 'one'</returns>
        public override GF2nElement Increase()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);

            result.IncreaseThis();

            return(result);
        }
Beispiel #8
0
        /// <summary>
        /// Compute the product of this element and <c>factor</c>
        /// </summary>
        ///
        /// <param name="Factor">he factor</param>
        ///
        /// <returns>Returns <c>this * factor</c> </returns>
        public override IGFElement Multiply(IGFElement Factor)
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);

            result.MultiplyThisBy(Factor);

            return(result);
        }
Beispiel #9
0
        /// <summary>
        /// Compute the square root of this element and return the result in a new GF2nPolynomialElement
        /// </summary>
        ///
        /// <returns>Returns <c>this^1/2</c> (newly created)</returns>
        public override GF2nElement SquareRoot()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);

            result.SquareRootThis();

            return(result);
        }
Beispiel #10
0
        /// <summary>
        /// Squares this GF2nPolynomialElement by using precalculated values and reducing.
        /// <para>This is supposed to de fastest when using a trinomial or pentanomial as field polynomial.
        /// Use SquareMatrix when using a ordinary polynomial as field polynomial.</para>
        /// </summary>
        ///
        /// <returns></returns>
        public GF2nPolynomialElement SquarePreCalc()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);

            result.SquareThisPreCalc();
            result.ReduceThis();

            return(result);
        }
Beispiel #11
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));
        }
Beispiel #12
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));
        }
Beispiel #13
0
        /// <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 InvertSquare()
        {
            GF2nPolynomialElement n;
            GF2nPolynomialElement u;
            int i, j, k, b;

            if (IsZero())
            {
                throw new ArithmeticException();
            }

            // b = (n-1)
            b = mField.Degree - 1;
            // n = a
            n = new GF2nPolynomialElement(this);
            n.polynomial.ExpandN((mDegree << 1) + 32); // increase performance
            n.polynomial.ReduceN();
            // k = 1
            k = 1;

            // for i = (r-1) downto 0 do, r=bitlength(b)
            for (i = BigMath.FloorLog(b) - 1; i >= 0; i--)
            {
                // u = n
                u = new GF2nPolynomialElement(n);
                // for j = 1 to k do
                for (j = 1; j <= k; j++)
                {
                    u.SquareThisPreCalc(); // u = u^2
                }
                // n = nu
                n.MultiplyThisBy(u);
                // k = 2k
                k <<= 1;
                // if b(i)==1
                if ((b & _bitMask[i]) != 0)
                {
                    // n = n^2 * b
                    n.SquareThisPreCalc();
                    n.MultiplyThisBy(this);
                    // k = k+1
                    k += 1;
                }
            }

            // outpur n^2
            n.SquareThisPreCalc();

            return(n);
        }
Beispiel #14
0
        /// <summary>
        /// Returns the trace of this GF2nPolynomialElement
        /// </summary>
        ///
        /// <returns>The trace of this GF2nPolynomialElement</returns>
        public override int Trace()
        {
            GF2nPolynomialElement t = new GF2nPolynomialElement(this);
            int i;

            for (i = 1; i < mDegree; i++)
            {
                t.SquareThis();
                t.AddToThis(this);
            }

            if (t.IsOne())
            {
                return(1);
            }

            return(0);
        }
Beispiel #15
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 GF2nPolynomialElement))
            {
                return(false);
            }

            GF2nPolynomialElement otherElem = (GF2nPolynomialElement)Obj;

            if (mField != otherElem.mField)
            {
                if (!mField.FieldPolynomial.Equals(otherElem.mField.FieldPolynomial))
                {
                    return(false);
                }
            }

            return(polynomial.Equals(otherElem.polynomial));
        }
Beispiel #16
0
        /// <summary>
        /// Solves the quadratic equation <c>z^2 + z = this</c> if such a solution exists.
        /// <para>This method returns one of the two possible solutions.
        /// The other solution is <c>z + 1</c>. Use z.Increase() to compute this solution.</para>
        /// </summary>
        ///
        /// <returns>Returns a GF2nPolynomialElement representing one z satisfying the equation <c>z^2 + z = this</c></returns>
        public override GF2nElement SolveQuadraticEquation()
        {
            if (IsZero())
            {
                return(Zero((GF2nPolynomialField)mField));
            }

            if ((mDegree & 1) == 1)
            {
                return(HalfTrace());
            }

            // TODO this can be sped-up by precomputation of p and w's
            GF2nPolynomialElement z, w;

            do
            {
                // step 1.
                GF2nPolynomialElement p = new GF2nPolynomialElement(
                    (GF2nPolynomialField)mField, new Random());
                // step 2.
                z = Zero((GF2nPolynomialField)mField);
                w = (GF2nPolynomialElement)p.Clone();
                // step 3.
                for (int i = 1; i < mDegree; i++)
                {
                    // compute z = z^2 + w^2 * this
                    // and w = w^2 + p
                    z.SquareThis();
                    w.SquareThis();
                    z.AddToThis(w.Multiply(this));
                    w.AddToThis(p);
                }
            }while (w.IsZero()); // step 4.

            if (!Equals(z.Square().Add(z)))
            {
                throw new Exception();
            }

            // step 5.
            return(z);
        }
Beispiel #17
0
        /// <summary>
        /// Returns the half-trace of this GF2nPolynomialElement
        /// </summary>
        ///
        /// <returns>Returns a GF2nPolynomialElement representing the half-trace of this GF2nPolynomialElement</returns>
        private GF2nPolynomialElement HalfTrace()
        {
            if ((mDegree & 0x01) == 0)
            {
                throw new Exception();
            }

            int i;
            GF2nPolynomialElement h = new GF2nPolynomialElement(this);

            for (i = 1; i <= ((mDegree - 1) >> 1); i++)
            {
                h.SquareThis();
                h.SquareThis();
                h.AddToThis(this);
            }

            return(h);
        }
Beispiel #18
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!");
            }
        }
 /**
  * .
  *
  * @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);
 }
        /// <summary>
        /// Increase the element by one
        /// </summary>
        /// 
        /// <returns>Returns <c>this</c> + 'one'</returns>
        public override GF2nElement Increase()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);
            result.IncreaseThis();

            return result;
        }
        /// <summary>
        /// Squares this GF2nPolynomialElement by using precalculated values and reducing.
        /// <para>This is supposed to de fastest when using a trinomial or pentanomial as field polynomial.
        /// Use SquareMatrix when using a ordinary polynomial as field polynomial.</para>
        /// </summary>
        /// 
        /// <returns></returns>
        public GF2nPolynomialElement SquarePreCalc()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);
            result.SquareThisPreCalc();
            result.ReduceThis();

            return result;
        }
Beispiel #22
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("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>
        /// 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>
        /// Calculates <c>this</c> to the power of <c>K</c> and returns the result in a new GF2nPolynomialElement
        /// </summary>
        /// 
        /// <param name="K">The power</param>
        /// 
        /// <returns>Returns <c>this</c>^<c>K</c> in a new GF2nPolynomialElement</returns>
        public GF2nPolynomialElement Power(int K)
        {
            if (K == 1)
                return new GF2nPolynomialElement(this);

            GF2nPolynomialElement result = GF2nPolynomialElement.One((GF2nPolynomialField)mField);
            if (K == 0)
                return result;

            GF2nPolynomialElement x = new GF2nPolynomialElement(this);
            x.polynomial.ExpandN((x.mDegree << 1) + 32); // increase performance
            x.polynomial.ReduceN();

            for (int i = 0; i < mDegree; i++)
            {
                if ((K & (1 << i)) != 0)
                    result.MultiplyThisBy(x);

                x.Square();
            }

            return result;
        }
        /// <summary>
        /// Solves the quadratic equation <c>z^2 + z = this</c> if such a solution exists.
        /// <para>This method returns one of the two possible solutions.
        /// The other solution is <c>z + 1</c>. Use z.Increase() to compute this solution.</para>
        /// </summary>
        /// 
        /// <returns>Returns a GF2nPolynomialElement representing one z satisfying the equation <c>z^2 + z = this</c></returns>
        public override GF2nElement SolveQuadraticEquation()
        {
            if (IsZero())
                return Zero((GF2nPolynomialField)mField);

            if ((mDegree & 1) == 1)
                return HalfTrace();

            // TODO this can be sped-up by precomputation of p and w's
            GF2nPolynomialElement z, w;
            do
            {
                // step 1.
                GF2nPolynomialElement p = new GF2nPolynomialElement(
                    (GF2nPolynomialField)mField, new Random());
                // step 2.
                z = Zero((GF2nPolynomialField)mField);
                w = (GF2nPolynomialElement)p.Clone();
                // step 3.
                for (int i = 1; i < mDegree; i++)
                {
                    // compute z = z^2 + w^2 * this
                    // and w = w^2 + p
                    z.SquareThis();
                    w.SquareThis();
                    z.AddToThis(w.Multiply(this));
                    w.AddToThis(p);
                }
            }
            while (w.IsZero()); // step 4.

            if (!Equals(z.Square().Add(z)))
                throw new Exception();

            // step 5.
            return z;
        }
 /// <summary>
 /// Squares this GF2nPolynomialElement by shifting left its Bitstring and reducing.
 /// <para>This is supposed to be the slowest method. Use SquarePreCalc or SquareMatrix instead.</para>
 /// </summary>
 /// 
 /// <returns></returns>
 public GF2nPolynomialElement SquareBitwise()
 {
     GF2nPolynomialElement result = new GF2nPolynomialElement(this);
     result.SquareThisBitwise();
     result.ReduceThis();
     return result;
 }
 /// <summary>
 /// Squares this GF2nPolynomialElement using GF2nField's 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>
 /// 
 /// <returns>Returns <c>this^2</c> (newly created)</returns>
 public GF2nPolynomialElement SquareMatrix()
 {
     GF2nPolynomialElement result = new GF2nPolynomialElement(this);
     result.SquareThisMatrix();
     result.ReduceThis();
     return result;
 }
        /// <summary>
        /// Compute the sum of this element and <c>Addend</c>.
        /// </summary>
        /// 
        /// <param name="Addend">The addend</param>
        /// 
        /// <returns>Returns <c>this + other</c></returns>
        public override IGFElement Add(IGFElement Addend)
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);
            result.AddToThis(Addend);

            return result;
        }
Beispiel #29
0
 /**
  * .
  *
  * @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);
 }
        /// <summary>
        /// Returns the half-trace of this GF2nPolynomialElement
        /// </summary>
        /// 
        /// <returns>Returns a GF2nPolynomialElement representing the half-trace of this GF2nPolynomialElement</returns>
        private GF2nPolynomialElement HalfTrace()
        {
            if ((mDegree & 0x01) == 0)
                throw new Exception();

            int i;
            GF2nPolynomialElement h = new GF2nPolynomialElement(this);

            for (i = 1; i <= ((mDegree - 1) >> 1); i++)
            {
                h.SquareThis();
                h.SquareThis();
                h.AddToThis(this);
            }

            return h;
        }
        /// <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));
        }
        /// <summary>
        /// Compute the product of this element and <c>factor</c>
        /// </summary>
        /// 
        /// <param name="Factor">he factor</param>
        /// 
        /// <returns>Returns <c>this * factor</c> </returns>
        public override IGFElement Multiply(IGFElement Factor)
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);
            result.MultiplyThisBy(Factor);

            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>
        /// 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 InvertSquare()
        {
            GF2nPolynomialElement n;
            GF2nPolynomialElement u;
            int i, j, k, b;

            if (IsZero())
                throw new ArithmeticException();

            // b = (n-1)
            b = mField.Degree - 1;
            // n = a
            n = new GF2nPolynomialElement(this);
            n.polynomial.ExpandN((mDegree << 1) + 32); // increase performance
            n.polynomial.ReduceN();
            // k = 1
            k = 1;

            // for i = (r-1) downto 0 do, r=bitlength(b)
            for (i = BigMath.FloorLog(b) - 1; i >= 0; i--)
            {
                // u = n
                u = new GF2nPolynomialElement(n);
                // for j = 1 to k do
                for (j = 1; j <= k; j++)
                    u.SquareThisPreCalc(); // u = u^2

                // n = nu
                n.MultiplyThisBy(u);
                // k = 2k
                k <<= 1;
                // if b(i)==1
                if ((b & _bitMask[i]) != 0)
                {
                    // n = n^2 * b
                    n.SquareThisPreCalc();
                    n.MultiplyThisBy(this);
                    // k = k+1
                    k += 1;
                }
            }

            // outpur n^2
            n.SquareThisPreCalc();

            return n;
        }
        /// <summary>
        /// Returns the trace of this GF2nPolynomialElement
        /// </summary>
        /// 
        /// <returns>The trace of this GF2nPolynomialElement</returns>
        public override int Trace()
        {
            GF2nPolynomialElement t = new GF2nPolynomialElement(this);
            int i;

            for (i = 1; i < mDegree; i++)
            {
                t.SquareThis();
                t.AddToThis(this);
            }

            if (t.IsOne())
                return 1;

            return 0;
        }
        /// <summary>
        /// Compute the square root of this element and return the result in a new GF2nPolynomialElement
        /// </summary>
        /// 
        /// <returns>Returns <c>this^1/2</c> (newly created)</returns>
        public override GF2nElement SquareRoot()
        {
            GF2nPolynomialElement result = new GF2nPolynomialElement(this);
            result.SquareRootThis();

            return result;
        }