/// <summary> /// Returns a Vandermonde matrix in the field (each element is modulu prime). /// </summary> public static ZpMatrix GetShamirRecombineMatrix(int matrixSize, int prime) { var A = new ZpMatrix(matrixSize, matrixSize, prime); if (matrixSize == 1) { A.data[0][0] = 1; return(A); } for (int i = 0; i < matrixSize; i++) { A.data[i][0] = 1; } for (int i = 0; i < matrixSize; i++) { A.data[i][1] = i + 1; } for (int i = 0; i < matrixSize; i++) { for (int j = 2; j < matrixSize; j++) { A.data[i][j] = Zp.Modulo(A.data[i][j - 1] * A.data[i][1], prime); } } return(A); }
public static ZpMatrix GetVandermondeMatrix(int rowNum, int colNum, long prime) { var A = new ZpMatrix(rowNum, colNum, prime); for (int j = 0; j < colNum; j++) { A.data[0][j] = 1; } if (rowNum == 1) { return(A); } for (int j = 0; j < colNum; j++) { A.data[1][j] = j + 1; } for (int j = 0; j < colNum; j++) { for (int i = 2; i < rowNum; i++) { A.data[i][j] = Zp.Modulo(A.data[i - 1][j] * A.data[1][j], prime); } } return(A); }
public ZpMatrix Times(ZpMatrix B) { var A = this; if (A.ColCount != B.RowCount) { throw new ArgumentException("Illegal matrix dimensions."); } if (A.Prime != B.Prime) { throw new ArgumentException("Matrix from different fields."); } // create initialized matrix (zero value to all elements) var C = new ZpMatrix(A.RowCount, B.ColCount, A.Prime); for (int i = 0; i < C.RowCount; i++) { for (int j = 0; j < C.ColCount; j++) { for (int k = 0; k < A.ColCount; k++) { C.data[i][j] = Modulo(C.data[i][j] + A.data[i][k] * B.data[k][j]); } } } return(C); }
public ZpMatrix Plus(ZpMatrix B) { var A = this; if ((B.RowCount != A.RowCount) || (B.ColCount != A.ColCount)) { throw new ArgumentException("Illegal matrix dimensions."); } if (A.Prime != B.Prime) { throw new ArgumentException("Trying to add Matrix from different fields."); } var C = new ZpMatrix(RowCount, ColCount, A.Prime); for (int i = 0; i < RowCount; i++) { for (int j = 0; j < ColCount; j++) { C.data[i][j] = Modulo(A.data[i][j] + B.data[i][j]); } } return(C); }
/// <summary> /// Evaluates the shares of secret with polynomial of degree 'polynomDeg' and 'numPlayers' players. /// </summary> private static IList <Zp> Share(Zp secret, int numPlayers, int polynomDeg, bool usePrimitiveShare, out IList <Zp> coeffs) { Debug.Assert(numPlayers > polynomDeg, "Polynomial degree cannot be greater than or equal to the number of players!"); // Create a random polynomial - f(x) // Note: Polynomial of degree d has d+1 coefficients var randomMatrix = ZpMatrix.GetRandomMatrix(1, polynomDeg + 1, secret.Prime); // The free variable in the Random Polynomial (i.e. f(x)) is the secret randomMatrix.SetMatrixCell(0, 0, secret); // Polynomial coefficients coeffs = randomMatrix.GetMatrixRow(0); // Create vanderMonde matrix ZpMatrix vanderMonde; if (usePrimitiveShare) { vanderMonde = ZpMatrix.GetPrimitiveVandermondeMatrix(polynomDeg + 1, numPlayers, secret.Prime); } else { vanderMonde = ZpMatrix.GetVandermondeMatrix(polynomDeg + 1, numPlayers, secret.Prime); } // Compute f(i) for the i-th player var sharesArr = randomMatrix.Times(vanderMonde).ZpVector; Debug.Assert(sharesArr.Length == numPlayers); return(sharesArr); }
/* Create and return N-by-N matrix that its first "trucToSize" elements in * its diagonal is "1" and the rest of the matrix is "0"*/ public static ZpMatrix GetTruncationMatrix(int matrixSize, int truncToSize, int prime) { var I = new ZpMatrix(matrixSize, matrixSize, prime); for (int i = 0; i < truncToSize; i++) { I.data[i][i] = 1; } return(I); }
/// <summary> /// Create and return the N-by-N identity matrix. /// </summary> public static ZpMatrix GetIdentityMatrix(int matrixSize, int prime) { var I = new ZpMatrix(matrixSize, matrixSize, prime); for (int i = 0; i < matrixSize; i++) { I.data[i][i] = 1; } return(I); }
/// <summary> /// Creates and return a random rowNum-by-colNum matrix with values between '0' and 'prime-1'. /// </summary> public static ZpMatrix GetRandomMatrix(int rowNum, int colNum, long prime) { var A = new ZpMatrix(rowNum, colNum, prime); for (int i = 0; i < rowNum; i++) { for (int j = 0; j < colNum; j++) { A.data[i][j] = Zp.Modulo((long)(StaticRandom.NextDouble() * (prime)), prime); } } return(A); }
/* r - Array of row indices, j0 - Initial column index, j1 - Final column index * return A(r(:),j0:j1) */ private ZpMatrix GetSubMatrix(int[] r, int j0, int j1) { var X = new ZpMatrix(r.Length, j1 - j0 + 1, Prime); var B = X.data; for (int i = 0; i < r.Length; i++) { for (int j = j0; j <= j1; j++) { B[i][j - j0] = data[r[i]][j]; } } return(X); }
public bool Eq(ZpMatrix B) { var A = this; if ((B.RowCount != A.RowCount) || (B.ColCount != A.ColCount) || (A.Prime != B.Prime)) { return(false); } for (int i = 0; i < RowCount; i++) { for (int j = 0; j < ColCount; j++) { if (A.data[i][j] != B.data[i][j]) { return(false); } } } return(true); }
public static ZpMatrix GetPrimitiveVandermondeMatrix(int rowNum, int colNum, long prime) { int primitive = NumTheoryUtils.GetFieldMinimumPrimitive(prime); if (primitive == 0) { throw new ArgumentException("Cannot create a primitive Vandermonde matrix from a non-prime number. "); } var A = new ZpMatrix(rowNum, colNum, prime); for (int j = 0; j < colNum; j++) { A.data[0][j] = 1; } if (rowNum == 1) { return(A); } /* This variable represents primitive^j for the j-th player*/ long primitive_j = 1; for (int j = 0; j < colNum; j++) { A.data[1][j] = primitive_j; primitive_j = Zp.Modulo(primitive_j * primitive, prime); } for (int j = 0; j < colNum; j++) { for (int i = 2; i < rowNum; i++) { A.data[i][j] = Zp.Modulo(A.data[i - 1][j] * A.data[1][j], prime); } } return(A); }
public static ZpMatrix GetVandermondeMatrix(int rowNum, IList <Zp> values, int prime) { int colNum = values.Count; var A = new ZpMatrix(rowNum, colNum, prime); for (int j = 0; j < colNum; j++) { A.data[0][j] = 1; } if (rowNum == 1) { return(A); } for (int j = 0; j < colNum; j++) { for (int i = 1; i < rowNum; i++) { A.data[i][j] = Zp.Modulo(A.data[i - 1][j] * values[j].Value, prime); } } return(A); }
private ZpMatrix(ZpMatrix A) : this(A.data, A.Prime) { }