Exemple #1
0
        /// <summary>
        /// This function uses backward substitution to find x of the linear equation system (LES) B*x = b,
        /// where A a triangle-matrix is (contains only zeros under the diagonal) and b is a vector.
        /// <para>If the multiplicative inverse of 0 is needed, an exception is thrown.
        /// In this case is the LES not solvable.</para>
        /// </summary>
        ///
        /// <exception cref="ArgumentException">Thrown if a multiplicative inverse of 0 is needed</exception>
        private void Substitute()
        {
            // for the temporary results of the operations in field
            short tmp, temp;

            temp = GF2Field.InvElem(_A[_A.Length - 1][_A.Length - 1]);

            if (temp == 0)
            {
                throw new CryptoAsymmetricSignException("ComputeInField:Substitute", "The equation system is not solvable!", new ArgumentException());
            }

            // backward substitution
            _X[_A.Length - 1] = GF2Field.MultElem(_A[_A.Length - 1][_A.Length], temp);
            for (int i = _A.Length - 2; i >= 0; i--)
            {
                tmp = _A[i][_A.Length];
                for (int j = _A.Length - 1; j > i; j--)
                {
                    temp = GF2Field.MultElem(_A[i][j], _X[j]);
                    tmp  = GF2Field.AddElem(tmp, temp);
                }

                temp = GF2Field.InvElem(_A[i][i]);

                if (temp == 0)
                {
                    throw new CryptoAsymmetricSignException("ComputeInField:Substitute", "Not a solvable equation system!", new ArgumentException());
                }

                _X[i] = GF2Field.MultElem(tmp, temp);
            }
        }
Exemple #2
0
        /// <summary>
        /// Elimination above the diagonal.
        /// <para>This function changes a matrix so that it contains only zeros above the diagonal(Ai,i) using only Gauss-Elimination operations.
        /// It is used in the inverse-function
        /// The result is stored in the global matrix A.</para>
        /// </summary>
        ///
        /// <exception cref="ArgumentException">Thrown if a multiplicative inverse of 0 is needed</exception>
        private void ComputeZerosAbove()
        {
            short tmp = 0;

            for (int k = _A.Length - 1; k > 0; k--) // the fixed row
            {
                for (int i = k - 1; i >= 0; i--)    // rows
                {
                    short factor1 = _A[i][k];
                    short factor2 = GF2Field.InvElem(_A[k][k]);

                    if (factor2 == 0)
                    {
                        throw new CryptoAsymmetricSignException("ComputeInField:ComputeZerosAbove", "Matrix not invertible!", new ArgumentException());
                    }

                    for (int j = k; j < 2 * _A.Length; j++) // columns
                    {
                        tmp      = GF2Field.MultElem(_A[k][j], factor2);
                        tmp      = GF2Field.MultElem(factor1, tmp);
                        _A[i][j] = GF2Field.AddElem(_A[i][j], tmp);
                    }
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Elimination under the diagonal.
        /// <para>This function changes a matrix so that it contains only zeros under the diagonal(Ai,i) using only Gauss-Elimination operations.
        /// It is used in solveEquaton as well as in the function for finding an inverse of a matrix: inverse.
        /// Both of them use the Gauss-Elimination Method.
        /// The result is stored in the global matrix A</para>
        /// </summary>
        ///
        /// <param name="ForInverse">Shows if the function is used by the solveEquation-function or by the inverse-function and according to this creates matrices of different sizes.</param>
        ///
        /// <exception cref="ArgumentException">Thrown if the multiplicative inverse of 0 is needed</exception>
        private void ComputeZerosUnder(bool ForInverse)
        {
            // the number of columns in the global A where the tmp results are stored
            int   length;
            short tmp = 0;

            // the function is used in inverse() - A should have 2 times more columns than rows
            if (ForInverse)
            {
                length = 2 * _A.Length;
            }
            // the function is used in solveEquation - A has 1 column more than rows
            else
            {
                length = _A.Length + 1;
            }

            // elimination operations to modify A so that that it contains only 0s under the diagonal
            for (int k = 0; k < _A.Length - 1; k++) // the fixed row
            {
                for (int i = k + 1; i < _A.Length; i++)
                {
                    short factor1 = _A[i][k];
                    short factor2 = GF2Field.InvElem(_A[k][k]);

                    // The element which multiplicative inverse is needed, is 0 in this case is the input matrix not invertible
                    if (factor2 == 0)
                    {
                        throw new CryptoAsymmetricSignException("ComputeInField:ComputeZerosUnder", "Matrix not invertible!", new ArgumentException());
                    }

                    for (int j = k; j < length; j++)
                    {// columns
                        // tmp=A[k,j] / A[k,k]
                        tmp = GF2Field.MultElem(_A[k][j], factor2);
                        // tmp = A[i,k] * A[k,j] / A[k,k]
                        tmp = GF2Field.MultElem(factor1, tmp);
                        // A[i,j]=A[i,j]-A[i,k]/A[k,k]*A[k,j];
                        _A[i][j] = GF2Field.AddElem(_A[i][j], tmp);
                    }
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// This function computes the inverse of a given matrix using the Gauss-Elimination method.
        /// <para>An exception is thrown if the matrix has no inverse</para>
        /// </summary>
        ///
        /// <param name="Coef">The matrix which inverse matrix is needed</param>
        ///
        /// <returns>The inverse matrix of the input matrix</returns>
        ///
        /// <exception cref="ArgumentException">Thrown if the given matrix is not invertible</exception>
        public short[][] Inverse(short[][] Coef)
        {
            try
            {
                short     factor;
                short[][] inverse;

                _A = ArrayUtils.CreateJagged <short[][]>(Coef.Length, 2 * Coef.Length);

                if (Coef.Length != Coef[0].Length)
                {
                    throw new CryptoAsymmetricSignException("ComputeInField:Inverse", "The matrix is not invertible!", new ArgumentException());
                }

                // prepare: Copy coef and the identity matrix into the global A
                for (int i = 0; i < Coef.Length; i++)
                {
                    // copy the input matrix coef into A
                    for (int j = 0; j < Coef.Length; j++)
                    {
                        _A[i][j] = Coef[i][j];
                    }

                    // copy the identity matrix into A.
                    for (int j = Coef.Length; j < 2 * Coef.Length; j++)
                    {
                        _A[i][j] = 0;
                    }

                    _A[i][i + _A.Length] = 1;
                }

                // Elimination operations to get the identity matrix from the left side of A, modify A to get 0s under the diagonal
                ComputeZerosUnder(true);

                // modify A to get only 1s on the diagonal: A[i][j] =A[i][j]/A[i][i]
                for (int i = 0; i < _A.Length; i++)
                {
                    factor = GF2Field.InvElem(_A[i][i]);
                    for (int j = i; j < 2 * _A.Length; j++)
                    {
                        _A[i][j] = GF2Field.MultElem(_A[i][j], factor);
                    }
                }

                //modify A to get only 0s above the diagonal.
                ComputeZerosAbove();

                // copy the result (the second half of A) in the matrix inverse
                inverse = ArrayUtils.CreateJagged <short[][]>(_A.Length, _A.Length);

                for (int i = 0; i < _A.Length; i++)
                {
                    for (int j = _A.Length; j < 2 * _A.Length; j++)
                    {
                        inverse[i][j - _A.Length] = _A[i][j];
                    }
                }

                return(inverse);
            }
            catch
            {
                // The matrix is not invertible! A new one should be generated!
                return(null);
            }
        }