public GGHModel(int dim, int l, VectorND errorVector) { this.dim = dim; this.l = l; k = (int)Math.Round(l * Math.Sqrt(dim)); do { GeneratePrivateKey(); GeneratePublicKey(); } while (privateKeyR.Det() == 0 || publicKeyB.Det() == 0); privateKeyR1 = privateKeyR.Invert(); publicKeyB1 = publicKeyB.Invert(); GenerateLattice(); if (errorVector == null || errorVector.dim != dim) { GenerateErrorVector(); } else { this.errorVector = errorVector; errorVectorIntern = new MatrixND(dim, 1); for (int i = 0; i < dim; i++) { errorVectorIntern[i, 0] = (double)errorVector.values[i]; } } }
public VectorND Encrypt(string message) { char[] chars = message.ToCharArray(); int rem; int blockCount = Math.DivRem(chars.Length, dim, out rem); if (rem > 0) { blockCount++; } VectorND cipher = new VectorND(dim * blockCount); for (int i = 0; i < blockCount; i++) { MatrixND messagePart = new MatrixND(dim, 1); for (int j = 0; j < dim && chars.Length > i * dim + j; j++) { messagePart[j, 0] = chars[i * dim + j]; } MatrixND cipherPart = publicKeyB * messagePart + errorVectorIntern; for (int j = 0; j < dim; j++) { cipher.values[i * dim + j] = (int)cipherPart[j, 0]; } } return(cipher); }
public void GeneratePublicKey() { //Generiere zunächst eine unimodulare Matrix mittels einer oberen Dreiecksmatrix Random random = new Random(); transU = new MatrixND(dim, dim); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { if (i == j) { transU[i, j] = random.NextDouble() < 0.5 ? 1 : -1; } else if (i > j) { transU[i, j] = random.Next(-maxValueForTransU, maxValueForTransU); } } } //transU1 = transU.Invert(); publicKeyB = privateKeyR * transU; }
public MatrixND SolveWith(MatrixND v) // Function solves Ax = v in confirmity with solution vector "v" { if (rows != cols) { throw new MException("The matrix is not square!"); } if (rows != v.rows) { throw new MException("Wrong number of results in solution vector!"); } if (L == null) { MakeLU(); } MatrixND b = new MatrixND(rows, 1); for (int i = 0; i < rows; i++) { b[i, 0] = v[pi[i], 0]; // switch two items in "v" due to permutation matrix } MatrixND z = SubsForth(L, b); MatrixND x = SubsBack(U, z); return(x); }
public string Decrypt(VectorND cipher) { List <char> result = new List <char>(); int blockCount = cipher.dim / dim; for (int i = 0; i < blockCount; i++) { MatrixND cipherVector = new MatrixND(dim, 1); for (int j = 0; j < dim; j++) { cipherVector[j, 0] = (double)cipher.values[i * dim + j]; } MatrixND babai = privateKeyR1 * cipherVector; for (int j = 0; j < dim; j++) { babai[j, 0] = Math.Round(babai[j, 0]); } MatrixND messageVector = publicKeyB1 * privateKeyR * babai; for (int j = 0; j < dim; j++) { int messageInt = (int)Math.Round(messageVector[j, 0]); if (messageInt == 0) { break; } result.Add(Convert.ToChar(messageInt)); } } return(new string(result.ToArray())); }
public void SetCol(MatrixND v, int k) { for (int i = 0; i < rows; i++) { mat[i, k] = v[i, 0]; } }
public void SetErrorVectorManually(VectorND newErrorVector) { errorVector = newErrorVector; dim = newErrorVector.dim; errorVectorIntern = new MatrixND(dim, 1); for (int i = 0; i < dim; i++) { errorVectorIntern[i, 0] = (int)errorVector.values[i]; } }
public LWEModel(MatrixND S, MatrixND A, MatrixND e, int q, int l) { this.S = S; this.A = A; this.e = e; this.q = q; this.l = l; B = (A * S + e) % q; }
private static void AminusBintoC(MatrixND A, int xa, int ya, MatrixND B, int xb, int yb, MatrixND C, int size) { for (int i = 0; i < size; i++) // rows { for (int j = 0; j < size; j++) { C[i, j] = A[ya + i, xa + j] - B[yb + i, xb + j]; } } }
private static void ACopytoC(MatrixND A, int xa, int ya, MatrixND C, int size) { for (int i = 0; i < size; i++) // rows { for (int j = 0; j < size; j++) { C[i, j] = A[ya + i, xa + j]; } } }
public static MatrixND IdentityMatrix(int iRows, int iCols) // Function generates the identity matrix { MatrixND matrixNd = ZeroMatrix(iRows, iCols); for (int i = 0; i < Math.Min(iRows, iCols); i++) { matrixNd[i, i] = 1; } return(matrixNd); }
public MatrixND GetCol(int k) { MatrixND m = new MatrixND(rows, 1); for (int i = 0; i < rows; i++) { m[i, 0] = mat[i, k]; } return(m); }
public void GenerateNewRandomVector() { Random random = new Random(); r = new MatrixND(1, m); for (int i = 0; i < m; i++) { r[0, i] = random.Next(2); } u = r * A; }
public bool DoTheKeysFit() { try { transU = (publicKeyB * privateKeyR1); return(Math.Abs(Math.Round(transU.Det(), 5)) == 1.00000); } catch (Exception) { return(false); } }
public static MatrixND Transpose(MatrixND m) // Matrix transpose, for any rectangular matrix { MatrixND t = new MatrixND(m.cols, m.rows); for (int i = 0; i < m.rows; i++) { for (int j = 0; j < m.cols; j++) { t[j, i] = m[i, j]; } } return(t); }
public static MatrixND ZeroMatrix(int iRows, int iCols) // Function generates the zero matrix { MatrixND matrixNd = new MatrixND(iRows, iCols); for (int i = 0; i < iRows; i++) { for (int j = 0; j < iCols; j++) { matrixNd[i, j] = 0; } } return(matrixNd); }
public MatrixND Duplicate() // Function returns the copy of this matrix { MatrixND matrixNd = new MatrixND(rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { matrixNd[i, j] = mat[i, j]; } } return(matrixNd); }
public MatrixND Decrypt(MatrixND cipher) { MatrixND result = (cipher - (u * S)) % q; MatrixND message = new MatrixND(1, l); for (int i = 0; i < l; i++) { double disZero = Math.Min(Math.Abs(q - result[0, i]), result[0, i]); double disOne = Math.Abs((Math.Floor((double)q / 2) - result[0, i]) % q); message[0, i] = disOne < disZero ? 1 : 0; } return(message); }
public MatrixND ToMatrixND() { MatrixND matrixND = new MatrixND(M, N); for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { matrixND[j, i] = (double)Vectors[i].values[j]; } } return(matrixND); }
private static MatrixND Multiply(double n, MatrixND m) // Multiplication by constant n { MatrixND r = new MatrixND(m.rows, m.cols); for (int i = 0; i < m.rows; i++) { for (int j = 0; j < m.cols; j++) { r[i, j] = m[i, j] * n; } } return(r); }
public void GenerateErrorVector() { Random random = new Random(); errorVector = new VectorND(dim); errorVectorIntern = new MatrixND(dim, 1); for (int i = 0; i < dim; i++) { int randomSigma = random.NextDouble() < 0.5 ? sigma : -sigma; errorVector.values[i] = randomSigma; errorVectorIntern[i, 0] = randomSigma; } }
private static void SafeACopytoC(MatrixND A, int xa, int ya, MatrixND C, int size) { for (int i = 0; i < size; i++) // rows { for (int j = 0; j < size; j++) // cols { C[i, j] = 0; if (xa + j < A.cols && ya + i < A.rows) { C[i, j] += A[ya + i, xa + j]; } } } }
public static MatrixND RandomMatrix(int iRows, int iCols, int dispersion) // Function generates the random matrix { Random random = new Random(); MatrixND matrixNd = new MatrixND(iRows, iCols); for (int i = 0; i < iRows; i++) { for (int j = 0; j < iCols; j++) { matrixNd[i, j] = random.Next(-dispersion, dispersion); } } return(matrixNd); }
public MatrixND GetP() // Function returns permutation matrix "P" due to permutation vector "pi" { if (L == null) { MakeLU(); } MatrixND matrixNd = ZeroMatrix(rows, cols); for (int i = 0; i < rows; i++) { matrixNd[pi[i], i] = 1; } return(matrixNd); }
private static MatrixND Mod(MatrixND m, int q) { MatrixND r = new MatrixND(m.rows, m.cols); for (int i = 0; i < r.rows; i++) { for (int j = 0; j < r.cols; j++) { r[i, j] = m[i, j] % q; if (r[i, j] < 0) { r[i, j] += q; } } } return(r); }
private static MatrixND Add(MatrixND m1, MatrixND m2) // Sčítání matic { if (m1.rows != m2.rows || m1.cols != m2.cols) { throw new MException("Matrices must have the same dimensions!"); } MatrixND r = new MatrixND(m1.rows, m1.cols); for (int i = 0; i < r.rows; i++) { for (int j = 0; j < r.cols; j++) { r[i, j] = m1[i, j] + m2[i, j]; } } return(r); }
public GGHModel(int dim, MatrixND privateKeyR, MatrixND publicKeyB, VectorND errorVector) { this.dim = dim; this.privateKeyR = privateKeyR; this.publicKeyB = publicKeyB; privateKeyR1 = privateKeyR.Invert(); publicKeyB1 = publicKeyB.Invert(); GenerateLattice(); this.errorVector = errorVector; errorVectorIntern = new MatrixND(dim, 1); for (int i = 0; i < dim; i++) { errorVectorIntern[i, 0] = (double)errorVector.values[i]; } }
private void GeneratePrivateKey() { Random random = new Random(); MatrixND S = new MatrixND(dim, dim); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { S[i, j] = random.Next(-l, l); } } MatrixND kI = k * MatrixND.IdentityMatrix(dim, dim); privateKeyR = kI + S; }
public void SetPrivateKeyManually(MatrixND newPrivateKeyR, bool generatePublicKey) { privateKeyR = newPrivateKeyR; privateKeyR1 = privateKeyR.Invert(); if (!generatePublicKey) { return; } do { GeneratePublicKey(); } while (publicKeyB.Det() == 0); publicKeyB1 = publicKeyB.Invert(); }
private static void SafeAminusBintoC(MatrixND A, int xa, int ya, MatrixND B, int xb, int yb, MatrixND C, int size) { for (int i = 0; i < size; i++) // rows { for (int j = 0; j < size; j++) // cols { C[i, j] = 0; if (xa + j < A.cols && ya + i < A.rows) { C[i, j] += A[ya + i, xa + j]; } if (xb + j < B.cols && yb + i < B.rows) { C[i, j] -= B[yb + i, xb + j]; } } } }