/// <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; }
/// <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> /// Multiply this vector with a permutation /// </summary> /// /// <param name="P">he permutation</param> /// /// <returns>Returns <c>this*p = p*this</c></returns> public override Vector Multiply(Permutation P) { int[] pVec = P.GetVector(); if (Length != pVec.Length) throw new ArithmeticException("permutation size and vector size mismatch"); int[] result = new int[Length]; for (int i = 0; i < pVec.Length; i++) result[i] = _vector[pVec[i]]; return new GF2mVector(_field, result); }
/// <summary> /// Compute the product of this permutation and another permutation /// </summary> /// /// <param name="p">The other permutation</param> /// /// <returns>Returns <c>this * P</c></returns> public Permutation RightMultiply(Permutation p) { if (p._perm.Length != _perm.Length) throw new ArgumentException("length mismatch"); Permutation result = new Permutation(_perm.Length); for (int i = _perm.Length - 1; i >= 0; i--) result._perm[i] = _perm[p._perm[i]]; return result; }
/// <summary> /// Compute the inverse permutation <c>P pow -1</c> /// </summary> /// /// <returns>Returns <c>this pow -1</c></returns> public Permutation ComputeInverse() { Permutation result = new Permutation(_perm.Length); for (int i = _perm.Length - 1; i >= 0; i--) result._perm[_perm[i]] = i; 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> /// Compute the product of a permutation matrix (which is generated from an n-permutation) and this matrix. /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns GF2Matrix <c>P*this</c></returns> public Matrix LeftMultiply(Permutation P) { int[] pVec = P.GetVector(); if (pVec.Length != RowCount) throw new ArithmeticException("GF2Matrix: length mismatch!"); int[][] result = new int[RowCount][]; for (int i = RowCount - 1; i >= 0; i--) result[i] = IntUtils.DeepCopy(_matrix[pVec[i]]); return new GF2Matrix(RowCount, result); }
/// <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> /// 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 product of this matrix and a permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns <c>this * P</c></returns> public abstract Matrix RightMultiply(Permutation P);
/// <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; }
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> /// Not implemented /// </summary> /// /// <param name="P">Permutation P</param> /// /// <returns>throws NotImplementedException</returns> public override Matrix RightMultiply(Permutation P) { throw new NotImplementedException(); }
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> /// Multiply this vector with a permutation /// </summary> /// /// <param name="P">The permutation</param> /// /// <returns>Returns <c>this*p = p*this</c></returns> public override Vector Multiply(Permutation P) { int[] pVec = P.GetVector(); if (Length != pVec.Length) throw new ArithmeticException("GF2Vector: Length mismatch!"); GF2Vector result = new GF2Vector(Length); for (int i = 0; i < pVec.Length; i++) { int e = _elements[pVec[i] >> 5] & (1 << (pVec[i] & 0x1f)); if (e != 0) result._elements[i >> 5] |= 1 << (i & 0x1f); } return result; }