예제 #1
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
            };
        }
예제 #2
0
    // Start is called before the first frame update
    void Start()
    {
        MatrixInt  a = new MatrixInt(1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
        Vector3Int d = new Vector3Int(1, 1, 1);

        Debug.Log(a * new Vector4Int(d, 1));
    }
예제 #3
0
        public static int Distance(MatrixInt vector1, MatrixInt vector2)
        {
            if (vector1.RowCount != vector2.RowCount)
            {
                throw new DimensionMismatchException("Number of rows in first vector does not equal number of rows in second vector.");
            }
            if (vector1.ColumnCount != vector2.ColumnCount)
            {
                throw new DimensionMismatchException("Number of columns in first vector does not equal number of columns in second vector.");
            }

            int distance = 0;

            for (var row = 0; row < vector1.RowCount; row++)
            {
                for (var col = 0; col < vector1.ColumnCount; col++)
                {
                    if (vector1.Data[row, col] != vector2.Data[row, col])
                    {
                        distance++;
                    }
                }
            }
            return(distance);
        }
예제 #4
0
        public MatrixInt DecryptMessage(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(PrivateKey.Mask[col]));
                }
            }
            #endregion
            //Debug.WriteLine(message);

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

            #region Correct Errors
            var correctedMessage = LinearCode.DecodeAndCorrect(message);
            #endregion
            //Debug.WriteLine(correctedMessage);

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

            return(decryptedMessage);
        }
        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);
        }
예제 #6
0
        public static MatrixInt Calculate(MatrixInt matrixLeft, MatrixInt matrixRight, GaloisField galoisField)
        {
            if (matrixLeft.ColumnCount != matrixRight.RowCount)
            {
                throw new DimensionMismatchException("Number of columns in first matrix does not equal number of rows in second matrix.");
            }

            var rowCount    = matrixLeft.RowCount;
            var columnCount = matrixRight.ColumnCount;

            var result = new MatrixInt(rowCount, columnCount);

            for (int row = rowCount - 1; row >= 0; row++)
            {
                for (int col = 0; col < columnCount; col++)
                {
                    int sum = 0;
                    for (int k = 0; k < matrixLeft.ColumnCount; k++)
                    {
                        var product = galoisField.MultiplyWords(matrixLeft.Data[row, k], matrixRight.Data[k, col]);
                        sum = galoisField.AddWords(sum, product);
                    }
                    result[row, col] = sum;
                }
            }
            return(result);
        }
예제 #7
0
        public MatrixInt DecryptMessage(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], PrivateKey.InverseMask[col]);
                }
            }
            #endregion
            Debug.WriteLine(message);

            #region Inverse permutation
            message = message.PermuteColumns(PrivateKey.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 decryptedMessage = MatrixAlgorithms.DotMultiplication(correctedMessage, PrivateKey.InverseScramblerMatrix, LinearCode.GaloisField);
            #endregion

            return(decryptedMessage);
        }
예제 #8
0
        public ReedSolomonCode(GaloisField galoisField, IParityCheckMatrixGenerator parityCheckMatrixGenerator)
        {
            GaloisField = galoisField;

            while (true)
            {
                ParityCheckMatrix = parityCheckMatrixGenerator.Generate(this);
                Debug.WriteLine(ParityCheckMatrix);

                if (Helper.Weight(ParityCheckMatrix) < Math.Ceiling(ParityCheckMatrix.RowCount * ParityCheckMatrix.ColumnCount * 0.7))
                {
                    continue;
                }

                try
                {
                    GeneratorMatrix = GeneratorMatrixCalculator.CalculateGeneratorMatrix(this);
                    Debug.WriteLine(GeneratorMatrix);
                }
                catch (LinearCodeException ex)
                {
                    Debug.WriteLine(ex.Message);
                    continue;
                }

                if (IsGeneratorMatrixValid(ParityCheckMatrix, GeneratorMatrix, GaloisField))
                {
                    break;
                }
            }
        }
예제 #9
0
        public static DataView GetBindable2DArray(MatrixInt matrix)
        {
            DataTable dataTable = new DataTable();

            for (int i = 0; i < matrix.ColumnCount; i++)
            {
                dataTable.Columns.Add(i.ToString(), typeof(Ref <int>));
            }
            for (int i = 0; i < matrix.RowCount; i++)
            {
                DataRow dataRow = dataTable.NewRow();
                dataTable.Rows.Add(dataRow);
            }
            DataView dataView = new DataView(dataTable);

            for (int i = 0; i < matrix.RowCount; i++)
            {
                for (int j = 0; j < matrix.ColumnCount; j++)
                {
                    int a = i;
                    int b = j;
                    dataView[a][b] = new Ref <int>(() => matrix[a, b], z => { matrix[a, b] = z; });
                }
            }
            return(dataView);
        }
예제 #10
0
        public static MatrixInt MatrixInverse(MatrixInt matrix, GaloisField galoisField)
        {
            var identity = Helper.GenerateIdentityMatrix(matrix.RowCount);
            var toSolve  = matrix | (identity);
            var inverse  = MatrixAlgorithms.Solve(toSolve, galoisField);

            return(inverse);
        }
예제 #11
0
        public void McElieseEllypticTest(int n, int k, int d, int t, int fieldPower, MatrixInt message, MatrixInt errorVector, MatrixInt scrambler, int[] permutation, int[] mask)
        {
            var galoisField      = new GaloisField(2, fieldPower);
            var mceliese         = new McElieseEllyptic(n, k, d, t, galoisField, scrambler, permutation, mask);
            var crytptogram      = mceliese.EncryptMessage(mceliese.PublicKey, message, errorVector);
            var decryptedMessage = mceliese.DecryptMessage(crytptogram);

            Assert.True(message == decryptedMessage);
        }
예제 #12
0
 public ReedSolomonCode(GaloisField galoisField, MatrixInt parityCheckMatrix)
 {
     GaloisField       = galoisField;
     ParityCheckMatrix = parityCheckMatrix;
     GeneratorMatrix   = GeneratorMatrixCalculator.CalculateGeneratorMatrix(this);
     if (!IsGeneratorMatrixValid(ParityCheckMatrix, GeneratorMatrix, GaloisField))
     {
         throw new LinearCodeException("Could not produce correct Generator matrix from provided ParityCheck matrix.");
     }
 }
예제 #13
0
        public MatrixInt EncryptMessage(PublicKey publicKey, MatrixInt message, MatrixInt errorVector)
        {
            var encryptedMessage = MatrixAlgorithms.DotMultiplication(message, publicKey.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);
        }
        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);
        }
예제 #15
0
 public GaloisField(int baseNumber, int fieldPower, MatrixInt polynomial)
 {
     Base                = baseNumber;
     FieldPower          = fieldPower;
     Polynomial          = polynomial;
     MaxValue            = (Base << FieldPower - 1);
     Field               = Generate();
     AdditionTable       = CalculateAdditionLookupTable(Field);
     MultiplicationTable = CalculateMultiplicationLookupTable(Field);
     DivisionTable       = CalculateDivisionLookupTable(Field);
 }
예제 #16
0
        private void BuildHappyMatrix(bool includeSelf = false)
        {
            List <string> guests = inputList.Select(l => l.Substring(0, l.IndexOf(' '))).Distinct().ToList();

            _happyMatrix = new MatrixInt(guests.Count + (includeSelf ? 1 : 0));

            foreach (string data in inputList)
            {
                string[] parts  = data.Split(' ');
                string   guestA = parts[0];
                string   guestB = parts[^ 1];
예제 #17
0
        public static MatrixInt GenerateIdentityMatrix(int size)
        {
            var rawResult = new int[size, size];

            for (var i = 0; i < size; i++)
            {
                rawResult[i, i] = 1;
            }
            var result = new MatrixInt(rawResult);

            return(result);
        }
예제 #18
0
        public void TestReedSolomonCode(int fieldPower, MatrixInt irreduciblePolynoimial, MatrixInt message, MatrixInt errorVector)
        {
            var galoisField     = new GaloisField(2, fieldPower, irreduciblePolynoimial);
            var generator       = new ParityCheckMatrixGeneratorGeneric();
            var reedSolomonCode = new ReedSolomonCode(galoisField, generator);

            var encodedMessage = reedSolomonCode.Encode(message, errorVector);

            var originalMessage = reedSolomonCode.DecodeAndCorrect(encodedMessage);

            Assert.True(message == originalMessage);
        }
예제 #19
0
        public static MatrixInt DecimalToBinary(int number)
        {
            var rawResult = new List <int>();

            while (number >= 1)
            {
                rawResult.Add(number % 2);
                number = number >> 1;
            }
            var result = new MatrixInt(rawResult);

            return(result);
        }
예제 #20
0
        private MatrixInt CalculateAdditionLookupTable(List <int> field)
        {
            var multiplicationTable = new MatrixInt(new int[field.Count, field.Count]);

            for (int row = 0; row < field.Count; row++)
            {
                for (int col = 0; col < field.Count; col++)
                {
                    multiplicationTable[row, col] = field.LastIndexOf(field[row] ^ field[col]);
                }
            }
            return(multiplicationTable);
        }
예제 #21
0
        public static MatrixInt Map(PolynomialDouble polynomial)
        {
            int[,] values = new int[1, polynomial.Degree];

            for (int i = 0; i < polynomial.Degree; i++)
            {
                values[0, i] = (int)Math.Round(polynomial.Coefficients[i]);
            }

            var result = new MatrixInt(values);

            return(result);
        }
예제 #22
0
        public void TestMcElieceCryptosystem(MatrixInt message, MatrixInt errorVector, MatrixInt scrambler, IList <int> permutation, IList <int> mask)
        {
            var galoisField = new GaloisField(2, 3);

            var generator       = new ParityCheckMatrixGeneratorGeneric();
            var reedSolomonCode = new ReedSolomonCode(galoisField, generator);

            var mcElieseCryptosystem = new McEliece(reedSolomonCode, scrambler, permutation, mask);

            var encryptedMessage = mcElieseCryptosystem.EncryptMessage(mcElieseCryptosystem.PublicKey, message, errorVector);
            var originalMessage  = mcElieseCryptosystem.DecryptMessage(encryptedMessage);

            Assert.True(message == originalMessage);
        }
        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);
        }
예제 #24
0
        public static MatrixInt GenerateScramblerMatrix(int numberOfRows, int numberOfCols)
        {
            var rawResult = new int[numberOfRows, numberOfCols];
            var rand      = new Random();

            for (var row = 0; row < numberOfRows; row++)
            {
                for (var col = 0; col < numberOfCols; col++)
                {
                    rawResult[row, col] = rand.Next(2);
                }
            }
            var result = new MatrixInt(rawResult);

            return(result);
        }
예제 #25
0
        public GaloisField(int baseNumber, int fieldPower)
        {
            if (!Constants.IrreduciblePolynoms.ContainsKey(fieldPower))
            {
                throw new GaloisFieldException($"It seems there is no fitting irreducible polynomial for such parameters: power={fieldPower}");
            }
            Base       = baseNumber;
            FieldPower = fieldPower;

            Polynomial          = Constants.IrreduciblePolynoms[fieldPower];
            MaxValue            = (Base << FieldPower - 1);
            Field               = Generate();
            AdditionTable       = CalculateAdditionLookupTable(Field);
            MultiplicationTable = CalculateMultiplicationLookupTable(Field);
            DivisionTable       = CalculateDivisionLookupTable(Field);
        }
예제 #26
0
        public PolynomialOnGaloisField(int degree, IList <int> coefficients, GaloisField galoisField)
        {
            _galoisField = galoisField;
            Terms        = CalculatePolynomialMembers(degree);

            _coefficients = new List <int>();
            for (int i = 0; i < Terms.RowCount; i++)
            {
                if (i >= coefficients.Count)
                {
                    _coefficients.Add(0);
                    continue;
                }
                _coefficients.Add(coefficients[i]);
            }
        }
예제 #27
0
        public void TestMethodCheckMult()
        {
            /// Создаем два объекта типа MatrixInt
            MatrixInt m1 = new MatrixInt(new int[, ] {
                { 1, 1 }, { 1, 1 }
            });
            MatrixInt m2 = new MatrixInt(new int[, ] {
                { 1, 1 }, { 1, 1 }
            });

            MatrixInt actual   = m1 * m2;
            MatrixInt expected = new MatrixInt(new int[, ] {
                { 1, 1 }, { 1, 1 }
            });

            Assert.AreEqual(expected, actual, "Тест не пройден!");
        }
예제 #28
0
        public MatrixInt Encode(MatrixInt message, MatrixInt errorVector)
        {
            if (errorVector.ColumnCount != N)
            {
                throw new DimensionMismatchException("Number of values in the mesage matrix does not equal number of values in the error vector.");
            }

            var encodedMessage = Encode(message);
            var rawResult      = encodedMessage.Data;

            for (int i = 0; i < encodedMessage.ColumnCount; i++)
            {
                rawResult[0, i] = GaloisField.AddWords(rawResult[0, i], errorVector.Data[0, i]);
            }

            return(encodedMessage);
        }
예제 #29
0
        public static int Weight(MatrixInt matrix)
        {
            var count = 0;

            for (var row = 0; row < matrix.RowCount; row++)
            {
                for (var col = 0; col < matrix.ColumnCount; col++)
                {
                    if (matrix[row, col] != 0)
                    {
                        count++;
                    }
                }
            }

            return(count);
        }
예제 #30
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);
        }