public static MatrixInt CalculateGeneratorMatrixAlt(ILinearCode linearCode)
        {
            var       generatorMatrix = new MatrixInt(linearCode.K, linearCode.N);
            var       system          = linearCode.ParityCheckMatrix.Clone();
            MatrixInt solution        = null;

            try
            {
                solution = MatrixAlgorithms.Solve(system, linearCode.GaloisField);
            }
            catch (SolveMatrixException)
            {
                throw new LinearCodeException("Could not produce correct Generator matrix from provided ParityCheck matrix.");
            }

            #region Assemble generator matrix
            for (int i = 0; i < linearCode.K; i++)
            {
                for (int j = 0; j < solution.RowCount; j++)
                {
                    generatorMatrix[i, j] = solution[j, i];
                }

                if (solution.RowCount < linearCode.N)
                {
                    generatorMatrix[i, linearCode.N - linearCode.K + i] = 1;
                }
            }
            #endregion

            return(generatorMatrix);
        }
Пример #2
0
        public McEliece(ILinearCode linearCode, MatrixInt scramblerMatrix, IList <int> permutation, IList <int> mask)
        {
            LinearCode = linearCode;
            PrivateKey = new PrivateKey
            {
                GeneratorMatrix = linearCode.GeneratorMatrix,
                ScramblerMatrix = scramblerMatrix,
                Permutation     = permutation,
                Mask            = mask
            };

            var encryptionMatrix = MatrixAlgorithms.DotMultiplication(scramblerMatrix, linearCode.GeneratorMatrix, linearCode.GaloisField);

            Debug.WriteLine(encryptionMatrix);
            encryptionMatrix = encryptionMatrix.PermuteColumns(PrivateKey.Permutation);
            Debug.WriteLine(encryptionMatrix);
            for (int col = 0; col < encryptionMatrix.ColumnCount; col++)
            {
                for (int row = 0; row < encryptionMatrix.RowCount; row++)
                {
                    encryptionMatrix[row, col] = linearCode.GaloisField.MultiplyWords(encryptionMatrix[row, col], mask[col]);
                }
            }
            Debug.WriteLine(encryptionMatrix + 1);

            PublicKey = new PublicKey
            {
                EncryptionMatrix     = encryptionMatrix,
                ErrorVectorMaxWeight = linearCode.MinimumDistance
            };
        }
Пример #3
0
        public static MatrixInt Decrypt(ILinearCode linearCode, IList <int> permutation, IList <int> mask, MatrixInt scramblerMatrix, ParityCheckMatrixGeneratorEllyptic generator, MatrixInt encryptedMessage)
        {
            var message = encryptedMessage.Clone();

            #region Unmask
            for (int col = 0; col < message.ColumnCount; col++)
            {
                for (int row = 0; row < message.RowCount; row++)
                {
                    message[row, col] = linearCode.GaloisField.MultiplyWords(message[row, col], linearCode.GaloisField.GetMultiplicativeInverse(mask[col]));
                }
            }
            #endregion
            Debug.WriteLine(message);

            #region Inverse permutation
            var inversePermutation = Helper.InversePermutation(permutation);
            message = message.PermuteColumns(inversePermutation);
            #endregion
            Debug.WriteLine(message);

            #region Correct Errors
            var correctedMessage = DecoderEllyptic.DecodeAndCorrect(linearCode, message, generator);
            #endregion
            Debug.WriteLine(correctedMessage);

            #region Apply the inverse scrambler matrix
            var inverseScramblerMatrix = MatrixAlgorithms.MatrixInverse(scramblerMatrix, linearCode.GaloisField);
            var decryptedMessage       = MatrixAlgorithms.DotMultiplication(correctedMessage, inverseScramblerMatrix, linearCode.GaloisField);
            #endregion

            return(decryptedMessage);
        }
        public MatrixInt Generate(ILinearCode linearCode)
        {
            if (_ellypticCurve is null)
            {
                _ellypticCurve = new EllypticCurve(linearCode.GaloisField);
                Points         = _ellypticCurve.CalculateAllZeroPoints();
            }

            if (Points.Count < linearCode.N)
            {
                throw new ParityCheckMatrixGeneratorException("The amout of acceptable point is too low for given linear code to generate ParityCheck Matrix.");
            }

            if (_polynomial is null)
            {
                _polynomial = new PolynomialOnGaloisField(_degree, linearCode.GaloisField);
            }

            Debug.WriteLine(_polynomial.Terms);

            #region Pick K random functions
            var functions = new List <int>();
            var j         = 0;
            while (j < (linearCode.D))
            {
                var rand = new Random();
                var r    = rand.Next(_polynomial.Terms.RowCount);
                if (!functions.Contains(r))
                {
                    functions.Add(r);
                    j++;
                }
            }
            Terms = new Terms(linearCode.D);
            for (var i = 0; i < functions.Count; i++)
            {
                Terms.SetTerm(i, _polynomial.Terms[functions[i], 0], _polynomial.Terms[functions[i], 1]);
            }
            Debug.WriteLine(Terms);
            #endregion

            #region Calculate parity check matrix
            var parityCheckMatrix = new MatrixInt(new int[linearCode.D, linearCode.N]);
            for (int row = 0; row < parityCheckMatrix.RowCount; row++)
            {
                for (int col = 0; col < parityCheckMatrix.ColumnCount; col++)
                {
                    parityCheckMatrix[row, col] = _polynomial.CalculateMember(functions[row], Points[col].x, Points[col].y);
                }
            }
            #endregion

            return(parityCheckMatrix);
        }
        public static MatrixInt CalculateGeneratorMatrix(ILinearCode linearCode)
        {
            var generatorMatrix = new MatrixInt(linearCode.K, linearCode.N);

            #region Init
            for (int i = 0; i < linearCode.K; i++)
            {
                for (int j = 0; j < linearCode.K; j++)
                {
                    if (i == j)
                    {
                        generatorMatrix[i, j] = 1;
                    }
                    else
                    {
                        generatorMatrix[i, j] = 0;
                    }
                }
            }
            #endregion

            #region Solve k systems of linear equasions on field elements
            for (int i = 0; i < linearCode.K; i++)
            {
                var systemA = linearCode.ParityCheckMatrix.GetRangeOfColumns(new RangeInt(linearCode.K, linearCode.N));
                var systemB = systemA | linearCode.ParityCheckMatrix.GetColumn(i);
                Debug.WriteLine(systemB);

                MatrixInt systemSolution;
                try
                {
                    systemSolution = MatrixAlgorithms.Solve(systemB, linearCode.GaloisField);
                }
                catch (SolveMatrixException)
                {
                    throw new LinearCodeException("Could not produce correct Generator matrix from provided ParityCheck matrix.");
                }

                #region CopyResults
                for (int row = 0; row < systemSolution.RowCount; row++)
                {
                    generatorMatrix[i, row + linearCode.K] = systemSolution[row, systemSolution.ColumnCount - 1];
                }
                #endregion
            }
            #endregion

            return(generatorMatrix);
        }
Пример #6
0
        public MatrixInt Generate(ILinearCode linearCode)
        {
            var rows      = 2 * linearCode.T;
            var rawResult = new int[rows, linearCode.GaloisField.WordCount];

            for (int row = 0; row < rows; row++)
            {
                for (int col = 0; col < linearCode.GaloisField.WordCount; col++)
                {
                    rawResult[row, col] = (row * col) % linearCode.GaloisField.WordCount;
                }
            }

            var H = new MatrixInt(rawResult) + 1;

            return(H);
        }
Пример #7
0
        public static int[] LocateErrors(ILinearCode linearCode, MatrixInt syndrome)
        {
            #region Error locator polynomial
            var rowCount    = linearCode.T;
            var columnCount = linearCode.T + 1;

            var system = new int[rowCount, columnCount];

            for (int row = 0; row < rowCount; row++)
            {
                for (int col = 0; col < columnCount; col++)
                {
                    system[row, col] = syndrome[0, row + col];
                }
            }
            var coefficients = MatrixAlgorithms.Solve(new MatrixInt(system), linearCode.GaloisField).Transpose();
            #endregion

            #region Calculate Error Positions
            var errorLocators = new int[linearCode.N];
            for (int position = 0, word = 1; position < linearCode.N; position++, word++)
            {
                var sum = coefficients[0, 0];
                for (int i = 1; i < coefficients.ColumnCount; i++)
                {
                    var wordPower = linearCode.GaloisField.Power(word, i);
                    var wordToAdd = linearCode.GaloisField.MultiplyWords(coefficients[0, i], wordPower);
                    sum = linearCode.GaloisField.AddWords(sum, wordToAdd);
                }

                var lastWord = linearCode.GaloisField.Power(word, linearCode.T);
                sum = linearCode.GaloisField.AddWords(sum, lastWord);

                errorLocators[position] = sum;
            }
            #endregion
            return(errorLocators);
        }
Пример #8
0
        public static int[] LocateErrors(ILinearCode linearCode, MatrixInt syndrome, ParityCheckMatrixGeneratorEllyptic generator)
        {
            #region Error locator polynomial
            var rowCount    = linearCode.T;
            var columnCount = linearCode.T + 1;

            var system = new int[rowCount, columnCount];

            for (int row = 0; row < rowCount; row++)
            {
                for (int col = 0; col < columnCount - 1; col++)
                {
                    system[row, col] = syndrome[0, generator.Terms[(row + col), linearCode.T - 2]];
                }
                system[row, columnCount - 1] = syndrome[0, generator.Terms[row, linearCode.T - 1]];
            }
            var coefficients = MatrixAlgorithms.Solve(new MatrixInt(system), linearCode.GaloisField).Transpose();
            #endregion

            #region Calculate Error Positions
            var errorLocators = new int[linearCode.N];
            for (int position = 0; position < linearCode.N; position++)
            {
                var sum = 0;
                for (int i = 0; i < linearCode.T; i++)
                {
                    var wordToAdd = linearCode.GaloisField.MultiplyWords(coefficients[0, i], linearCode.GaloisField.Power(generator.Points[position].x, i));
                    sum = linearCode.GaloisField.AddWords(sum, wordToAdd);
                }

                sum = linearCode.GaloisField.AddWords(sum, generator.Points[position].y);

                errorLocators[position] = sum;
            }
            #endregion
            return(errorLocators);
        }
Пример #9
0
        public static MatrixInt Encrypt(ILinearCode linearCode, MatrixInt scramblerMatrix, IList <int> permutation, IList <int> mask, ParityCheckMatrixGeneratorEllyptic generator, MatrixInt message, MatrixInt errorVector)
        {
            var encryptionMatrix = MatrixAlgorithms.DotMultiplication(scramblerMatrix, linearCode.GeneratorMatrix, linearCode.GaloisField);

            Debug.WriteLine(encryptionMatrix);
            encryptionMatrix = encryptionMatrix.PermuteColumns(permutation);
            Debug.WriteLine(encryptionMatrix);
            for (int col = 0; col < encryptionMatrix.ColumnCount; col++)
            {
                for (int row = 0; row < encryptionMatrix.RowCount; row++)
                {
                    encryptionMatrix[row, col] = linearCode.GaloisField.MultiplyWords(encryptionMatrix[row, col], mask[col]);
                }
            }
            Debug.WriteLine(encryptionMatrix);

            var encryptedMessage = MatrixAlgorithms.DotMultiplication(message, encryptionMatrix, linearCode.GaloisField);

            for (int i = 0; i < encryptedMessage.ColumnCount; i++)
            {
                encryptedMessage[0, i] = linearCode.GaloisField.AddWords(encryptedMessage[0, i], errorVector[0, i]);
            }
            return(encryptedMessage);
        }
Пример #10
0
        public static MatrixInt DecodeAndCorrect(ILinearCode linearCode, MatrixInt message, ParityCheckMatrixGeneratorEllyptic generator)
        {
            if (message.ColumnCount != linearCode.ParityCheckMatrix.ColumnCount)
            {
                throw new DimensionMismatchException("Incorrect length of message. Meesage length should be equal number of columns in parity check matrix.");
            }

            #region Calculate syndrome
            var syndrome = MatrixAlgorithms.DotMultiplication(message, linearCode.ParityCheckMatrix.Transpose(), linearCode.GaloisField);
            #endregion

            #region Locate errors
            var errorLocators = ErrorLocatorEllyptic.LocateErrors(linearCode, syndrome, generator);

            var errorCount = errorLocators.Where(v => v == 0).Count();
            #endregion

            Debug.WriteLine(linearCode.ParityCheckMatrix);
            #region Caclulate Error vector
            var system = new MatrixInt(linearCode.D, errorCount);
            for (int row = 0; row < linearCode.D; row++)
            {
                for (int col = 0, i = 0; col < linearCode.N; col++)
                {
                    if (errorLocators[col] == 0)
                    {
                        system[row, i] = linearCode.ParityCheckMatrix[row, col];
                        i++;
                    }
                }
            }
            Debug.WriteLine(system);
            system |= syndrome.Transpose();
            Debug.WriteLine(system);
            var errorVectorValues = MatrixAlgorithms.Solve(system, linearCode.GaloisField);

            var errorVector = new int[errorLocators.Length];
            for (int i = 0, j = 0; i < errorVector.Length; i++)
            {
                if (errorLocators[i] == 0)
                {
                    errorVector[i] = errorVectorValues[j, 0];
                    j++;
                }
                else
                {
                    errorVector[i] = 0;
                }
            }
            #endregion


            var rawOriginalMessage = new int[linearCode.K];

            for (int i = 0; i < linearCode.K; i++)
            {
                rawOriginalMessage[i] = linearCode.GaloisField.AddWords(message.Data[0, i + linearCode.D], errorVector[i + linearCode.D]);
            }

            var originalMessage = new MatrixInt(rawOriginalMessage);
            return(originalMessage);
        }
Пример #11
0
        public static MatrixInt DecodeAndCorrect(ILinearCode linearCode, MatrixInt message)
        {
            if (message.ColumnCount != linearCode.ParityCheckMatrix.ColumnCount)
            {
                throw new DimensionMismatchException("Incorrect length of message. Meesage length should be equal number of columns in parity check matrix.");
            }

            #region Calculate syndrome
            var syndrome = MatrixAlgorithms.DotMultiplication(message, linearCode.ParityCheckMatrix.Transpose(), linearCode.GaloisField);
            #endregion

            var errorLocations = ErrorLocatorDefault.LocateErrors(linearCode, syndrome);

            #region Caclulate Error vector
            var rowCount    = linearCode.T;
            var columnCount = linearCode.T + 1;

            var system = new int[rowCount, columnCount];
            #region Find error positions
            var errorNumber = 0;
            for (int errorPosition = 0; errorPosition < linearCode.N; errorPosition++)
            {
                if (errorLocations[errorPosition] == 0)
                {
                    for (int row = 0; row < rowCount; row++)
                    {
                        system[row, errorNumber] = linearCode.ParityCheckMatrix[row, errorPosition];
                    }
                    errorNumber++;
                }
            }

            for (int i = 0; i < rowCount; i++)
            {
                system[i, columnCount - 1] = syndrome[0, i];
            }
            #endregion

            #region Find error values
            var weights = MatrixAlgorithms.Solve(new MatrixInt(system), linearCode.GaloisField);
            #endregion

            #region Recreate complete error vector
            var rawErrorVector = new int[linearCode.N];

            errorNumber = 0;
            for (int i = 0; i < linearCode.N; i++)
            {
                if (errorLocations[i] == 0)
                {
                    rawErrorVector[i] = weights.Data[errorNumber, 0];
                    errorNumber++;
                    continue;
                }
                rawErrorVector[i] = 0;
            }
            #endregion

            #endregion

            var rawOriginalMessage = new int[linearCode.K];

            for (int i = 0; i < linearCode.K; i++)
            {
                rawOriginalMessage[i] = linearCode.GaloisField.AddWords(message.Data[0, i], rawErrorVector[i]);
            }

            var originalMessage = new MatrixInt(rawOriginalMessage);
            return(originalMessage);
        }