/// <summary> /// Given a check matrix <c>H</c>, compute matrices <c>S</c>, <c>M</c>, and a random permutation <c>P</c> such that /// <c>S*H*P = (Id|M)</c>. Return <c>S^-1</c>, <c>M</c>, and the systematic form of H /// </summary> /// /// <param name="H">The check matrix</param> /// <param name="SecRnd">The source of randomness</param> /// /// <returns>Returns the tuple <c>(S^-1, M, P)</c></returns> public static MaMaPe ComputeSystematicForm(GF2Matrix H, IRandom SecRnd) { MaMaPe mmp = null; object lockobj = new object(); if (ParallelUtils.IsParallel) { Func <bool> condFn = () => mmp == null; ParallelUtils.Loop(new ParallelOptions(), condFn, loopState => { MaMaPe mmp2 = GetMMP(H, SecRnd); if (mmp2 != null) { lock (mmp2) { mmp = mmp2; } } }); } else { do { mmp = GetMMP(H, SecRnd); }while (mmp == null); } return(mmp); }
/// <summary> /// Compute the product of this matrix and a permutation matrix which is generated from an n-permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns GF2Matrix <c>this*P</c></returns> public override Matrix RightMultiply(Permutation P)//3 { int[] pVec = P.GetVector(); if (pVec.Length != ColumnCount) { throw new ArithmeticException("GF2Matrix: Length mismatch!"); } GF2Matrix result = new GF2Matrix(RowCount, ColumnCount); for (int i = ColumnCount - 1; i >= 0; i--) { int q = IntUtils.URShift(i, 5); int r = i & 0x1f; int pq = IntUtils.URShift(pVec[i], 5); int pr = pVec[i] & 0x1f; for (int j = RowCount - 1; j >= 0; j--) { result._matrix[j][q] |= ((IntUtils.URShift(_matrix[j][pq], pr)) & 1) << r; } } return(result); }
/// <summary> /// Given a check matrix <c>H</c>, compute matrices <c>S</c>, <c>M</c>, and a random permutation <c>P</c> such that /// <c>S*H*P = (Id|M)</c>. Return <c>S^-1</c>, <c>M</c>, and the systematic form of H /// </summary> /// /// <param name="H">The check matrix</param> /// <param name="SecRnd">The source of randomness</param> /// /// <returns>Returns the tuple <c>(S^-1, M, P)</c></returns> public static MaMaPe ComputeSystematicForm(GF2Matrix H, IRandom SecRnd) { MaMaPe mmp = null; object lockobj = new object(); if (ParallelUtils.IsParallel) { Func<bool> condFn = () => mmp == null; ParallelUtils.Loop(new ParallelOptions(), condFn, loopState => { MaMaPe mmp2 = GetMMP(H, SecRnd); if (mmp2 != null) { lock (mmp2) { mmp = mmp2; } } }); } else { do { mmp = GetMMP(H, SecRnd); } while (mmp == null); } return mmp; }
private static GF2Matrix InvertMatrix(GF2Matrix Matrix) { try { return((GF2Matrix)Matrix.ComputeInverse()); } catch { return(null); } }
/// <summary> /// Copy constructor /// </summary> /// /// <param name="A">A GF2Matrix to copy</param> public GF2Matrix(GF2Matrix A) { ColumnCount = A.ColumnCount; RowCount = A.RowCount; _length = A._length; _matrix = new int[A._matrix.Length][]; for (int i = 0; i < _matrix.Length; i++) { _matrix[i] = IntUtils.DeepCopy(A._matrix[i]); } }
/// <summary> /// Initialize this class CCA2 MPKCS using encoded byte arrays /// </summary> /// /// <param name="N">Length of the code</param> /// <param name="K">The dimension of the code</param> /// <param name="Gf">Encoded field polynomial defining the finite field <c>GF(2^m)</c></param> /// <param name="Gp">Encoded irreducible Goppa polynomial</param> /// <param name="P">The encoded permutation</param> /// <param name="H">Encoded canonical check matrix</param> /// <param name="QInv">The encoded matrix used to compute square roots in <c>(GF(2^m))^t</c></param> public MPKCPrivateKey(int N, int K, byte[] Gf, byte[] Gp, byte[] P, byte[] H, byte[][] QInv) { _N = N; _K = K; _gField = new GF2mField(Gf); _goppaPoly = new PolynomialGF2mSmallM(_gField, Gp); _P1 = new Permutation(P); _H = new GF2Matrix(H); _qInv = new PolynomialGF2mSmallM[QInv.Length]; for (int i = 0; i < QInv.Length; i++) _qInv[i] = new PolynomialGF2mSmallM(_gField, QInv[i]); }
/// <summary> /// Read a Public Key from a Stream /// </summary> /// /// <param name="KeyStream">An input stream containing an encoded key</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the key could not be loaded</exception> public MPKCPublicKey(Stream KeyStream) { try { BinaryReader reader = new BinaryReader(KeyStream); _N = reader.ReadInt32(); _T = reader.ReadInt32(); _G = new GF2Matrix(reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position))); } catch (Exception ex) { throw new CryptoAsymmetricException("MPKCPublicKey:CTor", "The Public key could not be loaded!", ex); } }
/// <summary> /// Compute the full form matrix <c>(this | Id)</c> from this matrix in left compact form. /// <para>Where <c>Id</c> is the <c>k x k</c> identity matrix and <c>k</c> is the number of rows of this matrix.</para> /// </summary> /// /// <returns>Returns <c>(this | Id)</c></returns> public GF2Matrix ExtendLeftCompactForm() { int newNumColumns = ColumnCount + RowCount; GF2Matrix result = new GF2Matrix(RowCount, newNumColumns); int ind = RowCount - 1 + ColumnCount; for (int i = RowCount - 1; i >= 0; i--, ind--) { // copy this matrix to first columns Array.Copy(_matrix[i], 0, result._matrix[i], 0, _length); // store the identity in last columns result._matrix[i][ind >> 5] |= 1 << (ind & 0x1f); } return(result); }
/// <summary> /// Create an nxn random regular matrix /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> private void AssignRandomRegularMatrix(int N, IRandom SecRnd) { RowCount = N; ColumnCount = N; _length = IntUtils.URShift((N + 31), 5); _matrix = ArrayUtils.CreateJagged <int[][]>(RowCount, _length); GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation perm = new Permutation(N, SecRnd); int[] p = perm.GetVector(); for (int i = 0; i < N; i++) { Array.Copy(rm._matrix[i], 0, _matrix[p[i]], 0, _length); } }
private static MaMaPe GetMMP(GF2Matrix H, IRandom SecRnd) { int n = H.ColumnCount; GF2Matrix s = null; Permutation p = new Permutation(n, SecRnd); GF2Matrix hp = (GF2Matrix)H.RightMultiply(p); GF2Matrix sInv = hp.LeftSubMatrix(); if ((s = InvertMatrix(sInv)) == null) { return(null); } GF2Matrix shp = (GF2Matrix)s.RightMultiply(hp); GF2Matrix m = shp.RightSubMatrix(); return(new MaMaPe(sInv, m, p)); }
/// <summary> /// Compute the full form matrix <c>(Id | this)</c> from this matrix in right compact form. /// <para>Where <c>Id</c> is the <c>k x k</c> identity matrix and <c>k</c> is the number of rows of this matrix.</para> /// </summary> /// /// <returns>Returns <c>(Id | this)</c></returns> public GF2Matrix ExtendRightCompactForm() { GF2Matrix result = new GF2Matrix(RowCount, RowCount + ColumnCount); int q = RowCount >> 5; int r = RowCount & 0x1f; for (int i = RowCount - 1; i >= 0; i--) { // store the identity in first columns result._matrix[i][i >> 5] |= 1 << (i & 0x1f); // copy this matrix to last columns if words have to be shifted if (r != 0) { int ind = q; // process all but last word for (int j = 0; j < _length - 1; j++) { // obtain matrix word int mw = _matrix[i][j]; // shift to correct position result._matrix[i][ind++] |= mw << r; result._matrix[i][ind] |= IntUtils.URShift(mw, (32 - r)); } // process last word int mwv = _matrix[i][_length - 1]; result._matrix[i][ind++] |= mwv << r; if (ind < result._length) { result._matrix[i][ind] |= IntUtils.URShift(mwv, (32 - r)); } } else { // no shifting necessary Array.Copy(_matrix[i], 0, result._matrix[i], q, _length); } } return(result); }
/// <summary> /// Get the submatrix of this matrix consisting of the rightmost <c>numColumns-numRows</c> columns /// </summary> /// /// <returns>Returns the <c>(numRows x (numColumns-numRows))</c> submatrix</returns> public GF2Matrix RightSubMatrix() { if (ColumnCount <= RowCount) { throw new ArithmeticException("GF2Matrix: empty submatrix!"); } int q = RowCount >> 5; int r = RowCount & 0x1f; GF2Matrix result = new GF2Matrix(RowCount, ColumnCount - RowCount); for (int i = RowCount - 1; i >= 0; i--) { // if words have to be shifted if (r != 0) { int ind = q; // process all but last word and shift to correct position for (int j = 0; j < result._length - 1; j++) { result._matrix[i][j] = (IntUtils.URShift(_matrix[i][ind++], r)) | (_matrix[i][ind] << (32 - r)); } // process last word result._matrix[i][result._length - 1] = IntUtils.URShift(_matrix[i][ind++], r); if (ind < _length) { result._matrix[i][result._length - 1] |= _matrix[i][ind] << (32 - r); } } else { // no shifting necessary Array.Copy(_matrix[i], q, result._matrix[i], 0, result._length); } } return(result); }
/// <summary> /// Compare this matrix with another object. /// </summary> /// /// <param name="Obj">The object to compare this to</param> /// <returns>Returns <c>true</c> if object is equal and has the same values</returns> public override bool Equals(Object Obj) { if (!(Obj is GF2Matrix)) { return(false); } GF2Matrix otherMatrix = (GF2Matrix)Obj; if ((RowCount != otherMatrix.RowCount) || (ColumnCount != otherMatrix.ColumnCount) || (_length != otherMatrix._length)) { return(false); } for (int i = 0; i < RowCount; i++) { if (!Compare.AreEqual(_matrix[i], otherMatrix._matrix[i])) { return(false); } } return(true); }
/// <summary> /// Construct a new MaMaPe container with the given parameters /// </summary> /// /// <param name="S">The first matrix</param> /// <param name="H">The second matrix</param> /// <param name="P">The permutation</param> public MaMaPe(GF2Matrix S, GF2Matrix H, Permutation P) { m_S = S; m_H = H; m_P = P; }
/// <summary> /// onstruct a new MatrixSet container with the given parameters /// </summary> /// /// <param name="G">The generator matrix</param> /// <param name="SetJ">The set of indices such that the submatrix of the generator matrix /// consisting of the specified columns is the identity</param> public MatrixSet(GF2Matrix G, int[] SetJ) { _g = G; _setJ = SetJ; }
/// <summary> /// Create a nxn random regular matrix and its inverse /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> /// <returns>The created random regular matrix and its inverse</returns> public static GF2Matrix[] CreateRandomRegularMatrixAndItsInverse(int N, IRandom SecRnd) { GF2Matrix[] result = new GF2Matrix[2]; // First part: create regular matrix int length = (N + 31) >> 5; GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation p = new Permutation(N, SecRnd); int[] pVec = p.GetVector(); int[][] matrix = ArrayUtils.CreateJagged<int[][]>(N, length); for (int i = 0; i < N; i++) Array.Copy(rm._matrix[pVec[i]], 0, matrix[i], 0, length); result[0] = new GF2Matrix(N, matrix); // Second part: create inverse matrix // inverse to lm GF2Matrix invLm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = 0; i < N; i++) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i + 1; j < N; j++) { int b = (lm._matrix[j][q]) & r; if (b != 0) { for (int k = 0; k <= q; k++) invLm._matrix[j][k] ^= invLm._matrix[i][k]; } } } // inverse to um GF2Matrix invUm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = N - 1; i >= 0; i--) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i - 1; j >= 0; j--) { int b = (um._matrix[j][q]) & r; if (b != 0) { for (int k = q; k < length; k++) invUm._matrix[j][k] ^= invUm._matrix[i][k]; } } } // inverse matrix result[1] = (GF2Matrix)invUm.RightMultiply(invLm.RightMultiply(p)); return result; }
/// <summary> /// Copy constructor /// </summary> /// /// <param name="A">A GF2Matrix to copy</param> public GF2Matrix(GF2Matrix A) { ColumnCount = A.ColumnCount; RowCount = A.RowCount; _length = A._length; _matrix = new int[A._matrix.Length][]; for (int i = 0; i < _matrix.Length; i++) _matrix[i] = IntUtils.DeepCopy(A._matrix[i]); }
/// <summary> /// Construct a new MaMaPe container with the given parameters /// </summary> /// /// <param name="S">The first matrix</param> /// <param name="H">The second matrix</param> /// <param name="P">The permutation</param> public MaMaPe(GF2Matrix S, GF2Matrix H, Permutation P) { _s = S; _h = H; _p = P; }
/// <summary> /// Compute the full form matrix <c>(this | Id)</c> from this matrix in left compact form. /// <para>Where <c>Id</c> is the <c>k x k</c> identity matrix and <c>k</c> is the number of rows of this matrix.</para> /// </summary> /// /// <returns>Returns <c>(this | Id)</c></returns> public GF2Matrix ExtendLeftCompactForm() { int newNumColumns = ColumnCount + RowCount; GF2Matrix result = new GF2Matrix(RowCount, newNumColumns); int ind = RowCount - 1 + ColumnCount; for (int i = RowCount - 1; i >= 0; i--, ind--) { // copy this matrix to first columns Array.Copy(_matrix[i], 0, result._matrix[i], 0, _length); // store the identity in last columns result._matrix[i][ind >> 5] |= 1 << (ind & 0x1f); } return result; }
/// <summary> /// Compute the product of this matrix and a matrix A over GF(2) /// </summary> /// /// <param name="M">A matrix A over GF(2)</param> /// /// <returns>Returns matrix product <c>this*M</c></returns> public override Matrix RightMultiply(Matrix M) { if (!(M is GF2Matrix)) throw new ArithmeticException("GF2Matrix: Matrix is not defined over GF(2)!"); if (M.RowCount != ColumnCount) throw new ArithmeticException("GF2Matrix: Length mismatch!"); GF2Matrix a = (GF2Matrix)M; GF2Matrix result = new GF2Matrix(RowCount, M.ColumnCount); int d; int rest = ColumnCount & 0x1f; if (rest == 0) d = _length; else d = _length - 1; for (int i = 0; i < RowCount; i++) { int count = 0; for (int j = 0; j < d; j++) { int e = _matrix[i][j]; for (int h = 0; h < 32; h++) { int b = e & (1 << h); if (b != 0) { for (int g = 0; g < a._length; g++) result._matrix[i][g] ^= a._matrix[count][g]; } count++; } } int e1 = _matrix[i][_length - 1]; for (int h = 0; h < rest; h++) { int b = e1 & (1 << h); if (b != 0) { for (int g = 0; g < a._length; g++) result._matrix[i][g] ^= a._matrix[count][g]; } count++; } } return result; }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { if (_gField != null) { _gField.Clear(); _gField = null; } if (_goppaPoly != null) { _goppaPoly.Clear(); _goppaPoly = null; } if (_H != null) { _H.Clear(); _H = null; } if (_P1 != null) { _P1.Clear(); _P1 = null; } if (_qInv != null) { for (int i = 0; i < _qInv.Length; i++) { _qInv[i].Clear(); _qInv[i] = null; } _qInv = null; } _K = 0; _N = 0; } catch { } _isDisposed = true; } }
/// <summary> /// Get the submatrix of this matrix consisting of the rightmost <c>numColumns-numRows</c> columns /// </summary> /// /// <returns>Returns the <c>(numRows x (numColumns-numRows))</c> submatrix</returns> public GF2Matrix RightSubMatrix() { if (ColumnCount <= RowCount) throw new ArithmeticException("GF2Matrix: empty submatrix!"); int q = RowCount >> 5; int r = RowCount & 0x1f; GF2Matrix result = new GF2Matrix(RowCount, ColumnCount - RowCount); for (int i = RowCount - 1; i >= 0; i--) { // if words have to be shifted if (r != 0) { int ind = q; // process all but last word and shift to correct position for (int j = 0; j < result._length - 1; j++) result._matrix[i][j] = (IntUtils.URShift(_matrix[i][ind++], r)) | (_matrix[i][ind] << (32 - r)); // process last word result._matrix[i][result._length - 1] = IntUtils.URShift(_matrix[i][ind++], r); if (ind < _length) result._matrix[i][result._length - 1] |= _matrix[i][ind] << (32 - r); } else { // no shifting necessary Array.Copy(_matrix[i], q, result._matrix[i], 0, result._length); } } return result; }
//3 /// <summary> /// Compute the product of this matrix and a permutation matrix which is generated from an n-permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns GF2Matrix <c>this*P</c></returns> public override Matrix RightMultiply(Permutation P) { int[] pVec = P.GetVector(); if (pVec.Length != ColumnCount) throw new ArithmeticException("GF2Matrix: Length mismatch!"); GF2Matrix result = new GF2Matrix(RowCount, ColumnCount); for (int i = ColumnCount - 1; i >= 0; i--) { int q = IntUtils.URShift(i, 5); int r = i & 0x1f; int pq = IntUtils.URShift(pVec[i], 5); int pr = pVec[i] & 0x1f; for (int j = RowCount - 1; j >= 0; j--) result._matrix[j][q] |= ((IntUtils.URShift(_matrix[j][pq], pr)) & 1) << r; } return result; }
/// <summary> /// Constructor used by McElieceKeyFactory /// </summary> /// /// <param name="N">The length of the code</param> /// <param name="T">The error correction capability of the code</param> /// <param name="G">The encoded generator matrix</param> public MPKCPublicKey(int N, int T, byte[] G) { _N = N; _T = T; _G = new GF2Matrix(G); }
private static MaMaPe GetMMP(GF2Matrix H, IRandom SecRnd) { int n = H.ColumnCount; GF2Matrix s = null; Permutation p = new Permutation(n, SecRnd); GF2Matrix hp = (GF2Matrix)H.RightMultiply(p); GF2Matrix sInv = hp.LeftSubMatrix(); if ((s = InvertMatrix(sInv)) == null) return null; GF2Matrix shp = (GF2Matrix)s.RightMultiply(hp); GF2Matrix m = shp.RightSubMatrix(); return new MaMaPe(sInv, m, p); }
/// <summary> /// Create an nxn random regular matrix /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> private void AssignRandomRegularMatrix(int N, IRandom SecRnd) { RowCount = N; ColumnCount = N; _length = IntUtils.URShift((N + 31), 5); _matrix = ArrayUtils.CreateJagged<int[][]>(RowCount, _length); GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation perm = new Permutation(N, SecRnd); int[] p = perm.GetVector(); for (int i = 0; i < N; i++) Array.Copy(rm._matrix[i], 0, _matrix[p[i]], 0, _length); }
/// <summary> /// Compute the full form matrix <c>(Id | this)</c> from this matrix in right compact form. /// <para>Where <c>Id</c> is the <c>k x k</c> identity matrix and <c>k</c> is the number of rows of this matrix.</para> /// </summary> /// /// <returns>Returns <c>(Id | this)</c></returns> public GF2Matrix ExtendRightCompactForm() { GF2Matrix result = new GF2Matrix(RowCount, RowCount + ColumnCount); int q = RowCount >> 5; int r = RowCount & 0x1f; for (int i = RowCount - 1; i >= 0; i--) { // store the identity in first columns result._matrix[i][i >> 5] |= 1 << (i & 0x1f); // copy this matrix to last columns if words have to be shifted if (r != 0) { int ind = q; // process all but last word for (int j = 0; j < _length - 1; j++) { // obtain matrix word int mw = _matrix[i][j]; // shift to correct position result._matrix[i][ind++] |= mw << r; result._matrix[i][ind] |= IntUtils.URShift(mw, (32 - r)); } // process last word int mwv = _matrix[i][_length - 1]; result._matrix[i][ind++] |= mwv << r; if (ind < result._length) result._matrix[i][ind] |= IntUtils.URShift(mwv, (32 - r)); } else { // no shifting necessary Array.Copy(_matrix[i], 0, result._matrix[i], q, _length); } } return result; }
/// <summary> /// Reads a Private Key from a Stream /// </summary> /// /// <param name="KeyStream">An input stream containing an encoded key</param> /// /// <exception cref="CryptoAsymmetricException">Thrown if the key could not be loaded</exception> public MPKCPrivateKey(Stream KeyStream) { try { int len; BinaryReader reader = new BinaryReader(KeyStream); // length _N = reader.ReadInt32(); // dimension _K = reader.ReadInt32(); // gf byte[] gf = reader.ReadBytes(GF_LENGTH); _gField = new GF2mField(gf); // gp len = reader.ReadInt32(); byte[] gp = reader.ReadBytes(len); _goppaPoly = new PolynomialGF2mSmallM(_gField, gp); // p1 len = reader.ReadInt32(); byte[] p1 = reader.ReadBytes(len); _P1 = new Permutation(p1); // check matrix len = reader.ReadInt32(); byte[] h = reader.ReadBytes(len); _H = new GF2Matrix(h); // length of first dimension len = reader.ReadInt32(); byte[][] qi = new byte[len][]; // get the qinv encoded array for (int i = 0; i < qi.Length; i++) { len = reader.ReadInt32(); qi[i] = reader.ReadBytes(len); } // assign qinv _qInv = new PolynomialGF2mSmallM[qi.Length]; for (int i = 0; i < QInv.Length; i++) _qInv[i] = new PolynomialGF2mSmallM(_gField, qi[i]); } catch (Exception ex) { throw new CryptoAsymmetricException("MPKCPrivateKey:CTor", "The Private key could not be loaded!", ex); } }
/// <summary> /// Create a nxn random regular matrix and its inverse /// </summary> /// /// <param name="N">Number of rows (and columns)</param> /// <param name="SecRnd">Source of randomness</param> /// <returns>The created random regular matrix and its inverse</returns> public static GF2Matrix[] CreateRandomRegularMatrixAndItsInverse(int N, IRandom SecRnd) { GF2Matrix[] result = new GF2Matrix[2]; // First part: create regular matrix int length = (N + 31) >> 5; GF2Matrix lm = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_LT, SecRnd); GF2Matrix um = new GF2Matrix(N, Matrix.MATRIX_TYPE_RANDOM_UT, SecRnd); GF2Matrix rm = (GF2Matrix)lm.RightMultiply(um); Permutation p = new Permutation(N, SecRnd); int[] pVec = p.GetVector(); int[][] matrix = ArrayUtils.CreateJagged <int[][]>(N, length); for (int i = 0; i < N; i++) { Array.Copy(rm._matrix[pVec[i]], 0, matrix[i], 0, length); } result[0] = new GF2Matrix(N, matrix); // Second part: create inverse matrix // inverse to lm GF2Matrix invLm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = 0; i < N; i++) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i + 1; j < N; j++) { int b = (lm._matrix[j][q]) & r; if (b != 0) { for (int k = 0; k <= q; k++) { invLm._matrix[j][k] ^= invLm._matrix[i][k]; } } } } // inverse to um GF2Matrix invUm = new GF2Matrix(N, Matrix.MATRIX_TYPE_UNIT); for (int i = N - 1; i >= 0; i--) { int rest = i & 0x1f; int q = IntUtils.URShift(i, 5); int r = 1 << rest; for (int j = i - 1; j >= 0; j--) { int b = (um._matrix[j][q]) & r; if (b != 0) { for (int k = q; k < length; k++) { invUm._matrix[j][k] ^= invUm._matrix[i][k]; } } } } // inverse matrix result[1] = (GF2Matrix)invUm.RightMultiply(invLm.RightMultiply(p)); return(result); }
private static GF2Matrix InvertMatrix(GF2Matrix Matrix) { try { return (GF2Matrix)Matrix.ComputeInverse(); } catch { return null; } }
private void Dispose(bool Disposing) { if (!_isDisposed && Disposing) { try { if (_G != null) { _G.Clear(); _G = null; } _N = 0; _T = 0; } catch { } _isDisposed = true; } }
/// <summary> /// Compute the product of this matrix and a matrix A over GF(2) /// </summary> /// /// <param name="M">A matrix A over GF(2)</param> /// /// <returns>Returns matrix product <c>this*M</c></returns> public override Matrix RightMultiply(Matrix M) { if (!(M is GF2Matrix)) { throw new ArithmeticException("GF2Matrix: Matrix is not defined over GF(2)!"); } if (M.RowCount != ColumnCount) { throw new ArithmeticException("GF2Matrix: Length mismatch!"); } GF2Matrix a = (GF2Matrix)M; GF2Matrix result = new GF2Matrix(RowCount, M.ColumnCount); int d; int rest = ColumnCount & 0x1f; if (rest == 0) { d = _length; } else { d = _length - 1; } for (int i = 0; i < RowCount; i++) { int count = 0; for (int j = 0; j < d; j++) { int e = _matrix[i][j]; for (int h = 0; h < 32; h++) { int b = e & (1 << h); if (b != 0) { for (int g = 0; g < a._length; g++) { result._matrix[i][g] ^= a._matrix[count][g]; } } count++; } } int e1 = _matrix[i][_length - 1]; for (int h = 0; h < rest; h++) { int b = e1 & (1 << h); if (b != 0) { for (int g = 0; g < a._length; g++) { result._matrix[i][g] ^= a._matrix[count][g]; } } count++; } } return(result); }
/// <summary> /// Initialize this class /// </summary> /// /// <param name="N">The length of the code</param> /// <param name="T">The error correction capability of the code</param> /// <param name="G">The generator matrix</param> internal MPKCPublicKey(int N, int T, GF2Matrix G) { _N = N; _T = T; _G = new GF2Matrix(G); }
/// <summary> /// Initialize this class for CCA2 MPKCS /// </summary> /// /// <param name="N">Length of the code</param> /// <param name="K">The dimension of the code</param> /// <param name="Gf">The finite field <c>GF(2^m)</c></param> /// <param name="Gp">The irreducible Goppa polynomial</param> /// <param name="P">The permutation</param> /// <param name="H">The canonical check matrix</param> /// <param name="QInv">The matrix used to compute square roots in <c>(GF(2^m))^t</c></param> internal MPKCPrivateKey(int N, int K, GF2mField Gf, PolynomialGF2mSmallM Gp, Permutation P, GF2Matrix H, PolynomialGF2mSmallM[] QInv) { _N = N; _K = K; _gField = Gf; _goppaPoly = Gp; _P1 = P; _H = H; _qInv = QInv; }