/// <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; }
/// <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); }
public static Zp Reconstruct(IList<Zp> sharedSecrets, int polyDeg, int prime) { if (sharedSecrets.Count < polyDeg) throw new System.ArgumentException("Polynomial degree cannot be bigger or equal to the number of shares"); // find Lagrange basis polynomials free coefficients var L = new Zp[polyDeg + 1]; for (int i = 0; i < polyDeg + 1; i++) L[i] = new Zp(prime, 1); int ix = 0; for (var i = new Zp(prime, 1); i < polyDeg + 2; i++, ix++) { for (var j = new Zp(prime, 1); j < polyDeg + 2; j++) { if (j != i) { var additiveInverse = j.AdditiveInverse; L[ix] = L[ix] * (additiveInverse / (i + additiveInverse)); // note: division done in finite-field } } } // find the secret by multiplying each share to the corresponding Lagrange's free coefficient var secret = new Zp(prime, 0); for (int i = 0; i < polyDeg + 1; i++) secret = secret + (L[i] * sharedSecrets[i]); return secret; }
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 Zp ConstMul(Zp operand) { var temp = new Zp(this); temp.num = Modulo(num * operand.Value); return(temp); }
/// <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 void SetMatrixCell(int rowNumber, int colNumber, Zp value) { if ((RowCount <= rowNumber) || (ColCount <= colNumber)) { throw new ArgumentException("Illegal matrix cell."); } data[rowNumber][colNumber] = value.Value; }
public Zp ConstDvide(Zp operand) { if (operand.num == 0) { throw new System.ArgumentException("Cannot divide by zero!"); } return(this * operand.MultipInverse); }
public static Zp EvalutePolynomialAtPoint(IList <Zp> polynomial, Zp point) { long evaluation = 0; for (int i = 0; i < polynomial.Count; i++) { evaluation += polynomial[i].Value * NumTheoryUtils.ModPow(point.Value, i, point.Prime); } return(new Zp(point.Prime, evaluation)); }
public override bool Equals(object obj) { if (!(obj is Zp)) { return(false); } Zp compare = (Zp)obj; return(Value == compare.Value && Prime == compare.Prime); }
/// <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); }
public Zp Calculate(Zp operand, Operation operation) { switch (operation) { case Operation.Add: return(Add(operand)); case Operation.Mul: return(Mul(operand)); case Operation.Sub: return(Sub(operand)); case Operation.Div: return(Div(operand)); default: throw new Exception("Unknown operation: " + operation); } }
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 Zp Reconstruct(IList <Zp> sharedSecrets, int polyDeg, int prime) { if (sharedSecrets.Count < polyDeg) { throw new System.ArgumentException("Polynomial degree cannot be bigger or equal to the number of shares"); } // find Lagrange basis polynomials free coefficients var L = new Zp[polyDeg + 1]; for (int i = 0; i < polyDeg + 1; i++) { L[i] = new Zp(prime, 1); } int ix = 0; for (var i = new Zp(prime, 1); i < polyDeg + 2; i++, ix++) { for (var j = new Zp(prime, 1); j < polyDeg + 2; j++) { if (j != i) { var additiveInverse = j.AdditiveInverse; L[ix] = L[ix] * (additiveInverse / (i + additiveInverse)); // note: division done in finite-field } } } // find the secret by multiplying each share to the corresponding Lagrange's free coefficient var secret = new Zp(prime, 0); for (int i = 0; i < polyDeg + 1; i++) { secret = secret + (L[i] * sharedSecrets[i]); } return(secret); }
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); }
public Zp(Zp toCopy) { this.Prime = toCopy.Prime; this.num = Modulo(toCopy.num, this.Prime); }
public Zp Sub(Zp operand) { num = Modulo(num - operand.Value); return this; }
public Zp Mul(Zp operand) { num = Modulo(num * operand.Value); return this; }
public Zp Div(Zp operand) { if (operand.num == 0) throw new ArgumentException("Cannot divide by zero!"); return this * operand.MultipInverse; }
/// <summary> /// Calculates the shares of a secret with polynomial of degree t and numPlayers players. /// The method also returns the array of coefficients of the polynomial. /// </summary> public static IList<Zp> Share(Zp secret, int numPlayers, int polyDeg, out IList<Zp> coeffs) { return Share(secret, numPlayers, polyDeg, false, out coeffs); }
public Zp Add(Zp operand) { num = Modulo(num + operand.Value); return(this); }
public Zp Mul(Zp operand) { num = Modulo(num * operand.Value); return(this); }
public BridgeJoinMessage(long pseudonym, Zp idShare) { Pseudonym = pseudonym; IdShare = idShare; }
/* calculate i mod prime */ private long Modulo(long i) { return(Zp.Modulo(i, Prime)); }
public Zp Add(Zp operand) { num = Modulo(num + operand.Value); return this; }
public Zp Calculate(Zp operand, Operation operation) { switch (operation) { case Operation.Add: return Add(operand); case Operation.Mul: return Mul(operand); case Operation.Sub: return Sub(operand); case Operation.Div: return Div(operand); default: throw new Exception("Unknown operation: " + operation); } }
public Zp ConstSub(Zp operand) { var temp = new Zp(this); temp.num = Modulo(num - operand.Value); return temp; }
public Zp Sub(Zp operand) { num = Modulo(num - operand.Value); return(this); }
public static Zp EvalutePolynomialAtPoint(IList<Zp> polynomial, Zp point) { long evaluation = 0; for (int i = 0; i < polynomial.Count; i++) { evaluation += polynomial[i].Value * NumTheoryUtils.ModPow(point.Value, i, point.Prime); } return new Zp(point.Prime, evaluation); }
/// <summary> /// Calculates the shares of a secret with polynomial of degree t and numPlayers players. /// The method also returns the array of coefficients of the polynomial. /// </summary> public static IList <Zp> Share(Zp secret, int numPlayers, int polyDeg, out IList <Zp> coeffs) { return(Share(secret, numPlayers, polyDeg, false, out coeffs)); }