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); }
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 }; }
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); }
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); }
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); }
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); }
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); }
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); }
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); }