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 McElieseEllyptic(int n, int k, int d, int t, GaloisField galoisField, MatrixInt scramblerMatrix = null, IList <int> permutation = null, IList <int> mask = null) { _generator = new ParityCheckMatrixGeneratorEllyptic(2); LinearCode = new LinearCode(n, k, d, t, galoisField); MatrixInt parityCheckMatrix = null; MatrixInt generatorMatrix = null; while (true) { parityCheckMatrix = _generator.Generate(LinearCode); LinearCode.ParityCheckMatrix = parityCheckMatrix; Debug.WriteLine(parityCheckMatrix); var minValueFillPercentage = 0.7; if (Helper.Weight(parityCheckMatrix) < Math.Ceiling(parityCheckMatrix.RowCount * parityCheckMatrix.ColumnCount * minValueFillPercentage)) { continue; } try { generatorMatrix = GeneratorMatrixCalculator.CalculateGeneratorMatrixAlt(LinearCode); Debug.WriteLine(generatorMatrix); } catch (LinearCodeException ex) { Debug.WriteLine(ex.Message); continue; } if (IsGeneratorMatrixValid(parityCheckMatrix, generatorMatrix, galoisField)) { LinearCode.GeneratorMatrix = generatorMatrix; break; } } if (scramblerMatrix is null) { scramblerMatrix = Helper.GenerateScramblerMatrix(LinearCode.K); while (true) { try { MatrixAlgorithms.MatrixInverse(scramblerMatrix, galoisField); break; } catch (SolveMatrixException) { Debug.WriteLine("Reattempting to generate scrambler matrix"); } } } if (permutation is null) { permutation = Helper.GeneratePermutaionList(LinearCode.N); } if (mask is null) { mask = Helper.GenerateMask(LinearCode.N, LinearCode.GaloisField); } var inverseMask = new List <int>(LinearCode.N); for (int i = 0; i < LinearCode.N; i++) { inverseMask.Add(LinearCode.GaloisField.GetMultiplicativeInverse(mask[i])); } PrivateKey = new PrivateKey { GeneratorMatrix = LinearCode.GeneratorMatrix, ScramblerMatrix = scramblerMatrix, InverseScramblerMatrix = MatrixAlgorithms.MatrixInverse(scramblerMatrix, galoisField), Permutation = permutation, InversePermutation = Helper.InversePermutation(permutation), Mask = mask, InverseMask = inverseMask }; var encryptionMatrix = MatrixAlgorithms.DotMultiplication(PrivateKey.ScramblerMatrix, 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], PrivateKey.Mask[col]); } } Debug.WriteLine(encryptionMatrix); PublicKey = new PublicKey { EncryptionMatrix = encryptionMatrix, }; }