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 }; }
// 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)); }
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); }
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); }
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); }
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); }
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; } } }
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); }
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); }
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); }
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."); } }
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); }
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); }
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];
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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]); } }
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, "Тест не пройден!"); }
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); }
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); }
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); }