Beispiel #1
0
        /// <summary>
        /// Implementation according to GRR.
        /// </summary>
        public virtual void RunReductionRandomization(Zp oldSecret)
        {
            // randomize the coeficients
            // generate a t degree polynomial, hi(x),
            // with a free coef that equals 'ab' and create share for users from it.
            var sharesValues = ShamirSharing.Share(oldSecret, NumParties, PolynomialDeg);
            var shareMsgs    = new List <ShareMsg <Zp> >();

            foreach (var shareValue in sharesValues)
            {
                shareMsgs.Add(new ShareMsg <Zp>(new Share <Zp>(shareValue), Stage.RandomizationReceive));
            }

            // send to the j-th user hi(j) and receive from every other k player hk(i)
            Send(shareMsgs);

            OnReceive((int)Stage.RandomizationReceive,
                      delegate(List <Msg> shares)
            {
                var vanderFirstRow =
                    ZpMatrix.GetSymmetricVanderMondeMatrix(NumParties, Prime)
                    .Transpose.Inverse.GetMatrixRow(0);

                // Calculate the value of the polynomial H(x) at i = H(i) as defined at GRR
                var tempSecret = new Zp(Prime, 0);
                for (int i = 0; i < NumParties; i++)
                {
                    tempSecret.Add(((shares[i] as ShareMsg <Zp>).Share as Share <Zp>).Value.Mul(vanderFirstRow[i]));
                }
            });
        }
Beispiel #2
0
        /// <summary>
        /// Creates a random polynomial f(x,y) and then to create from it for
        /// the i-th player two polynomials : fi(x) = f(x,w^i) and gi(y) = f(w^i,y).
        /// </summary>
        public static IList <SecretPolynomials> ShareByzantineCase(Zp secret,
                                                                   int numPlayers, int polynomDeg)
        {
            if (numPlayers <= 4 * polynomDeg)
            {
                throw new System.ArgumentException("Cannot use Byzantine algoritm -- numberOfPlayers <= 4*polynomDeg - " + "use regular computation instead");
            }

            // Creating the Random Polynomial - f(x , y)
            // Note : there are (t+1)^2 coefficiet for the polynomial including the free coefficient (the secret)
            // first  row  coef are of  (x^0,x^1,x^2,...,x^t)y^0, second  row  coef are (x^0, x1,...,x^t)y^1 and so forth...
            var randomMatrix_f_xy = ZpMatrix.GetRandomMatrix(polynomDeg + 1, polynomDeg + 1, secret.Prime);

            randomMatrix_f_xy.SetMatrixCell(0, 0, secret);
            var polynomialShares = new List <SecretPolynomials>();

            for (int i = 0; i < numPlayers; i++)
            {
                var pSecret = new SecretPolynomials();
                pSecret.Fi_xPolynomial = GenerateF_i_xPolynomial(randomMatrix_f_xy, secret, i);
                pSecret.Gi_yPolynomial = GenerateG_i_yPolynomial(randomMatrix_f_xy, secret, i);
                polynomialShares.Add(pSecret);
            }
            return(polynomialShares);
        }
Beispiel #3
0
        private static IList<Zp> GenerateF_i_xPolynomial(ZpMatrix f_x_y,
			Zp secret, int playerNum)
        {
            int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime);
            int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime);

            var y_values = new int[f_x_y.ColCount];
            for (int i = 0; i < f_x_y.ColCount; i++)
            {
                y_values[i] = NumTheoryUtils.ModPow(w_i, i, secret.Prime);
            }
            return f_x_y.MulMatrixByScalarsVector(y_values).SumMatrixRows();
        }
Beispiel #4
0
        // TODO: MAHDI: HAS WRONG ORDERING!
        private IList <Zp> GetMultStepCoeffsForCheaters(int j)
        {
            var rowsToRemove = new bool[NumParties];

            for (int i = 0; i < NumParties; i++)
            {
                rowsToRemove[i] = BadPlayers.Contains(i);
            }

            var vanderMonde    = ZpMatrix.GetSymmetricPrimitiveVandermondeMatrix(NumParties, Prime).Transpose;
            var filteredMatrix = vanderMonde.RemoveRowsFromMatrix(rowsToRemove).Inverse;

            return(filteredMatrix.GetMatrixRow(j));
        }
Beispiel #5
0
        private static IList <Zp> GenerateF_i_xPolynomial(ZpMatrix f_x_y,
                                                          Zp secret, int playerNum)
        {
            int w   = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime);
            int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime);

            var y_values = new int[f_x_y.ColCount];

            for (int i = 0; i < f_x_y.ColCount; i++)
            {
                y_values[i] = NumTheoryUtils.ModPow(w_i, i, secret.Prime);
            }
            return(f_x_y.MulMatrixByScalarsVector(y_values).SumMatrixRows());
        }
Beispiel #6
0
        private static IList<Zp> GenerateG_i_yPolynomial(ZpMatrix f_x_y,
			Zp secret, int playerNum)
        {
            int w = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime);
            int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime);

            var x_values = new Zp[f_x_y.RowCount];
            for (int i = 0; i < f_x_y.RowCount; i++)
            {
                x_values[i] = new Zp(secret.Prime, NumTheoryUtils.ModPow(w_i, i, secret.Prime));
            }

            var tempArr = f_x_y.Times(new ZpMatrix(x_values, VectorType.Column)).ZpVector;
            return tempArr;
        }
Beispiel #7
0
        private static ZpMatrix getWelchBerlekampMatrix(IList <Zp> XVlaues, IList <Zp> YVlaues, int n, int e, int prime)
        {
            var NVanderMonde = ZpMatrix.GetVandermondeMatrix(n - e, XVlaues, prime).Transpose;
            var EVanderMonde = ZpMatrix.GetVandermondeMatrix(e, XVlaues, prime).Transpose;

            int[] scalarVector = new int[YVlaues.Count];
            int   i            = 0;

            foreach (Zp zp in YVlaues)
            {
                scalarVector[i++] = -zp.Value;
            }

            EVanderMonde = EVanderMonde.MulMatrixByScalarsVector(scalarVector);
            return(ZpMatrix.GetConcatenationMatrix(NVanderMonde, EVanderMonde));
        }
Beispiel #8
0
        private static IList <Zp> GenerateG_i_yPolynomial(ZpMatrix f_x_y,
                                                          Zp secret, int playerNum)
        {
            int w   = NumTheoryUtils.GetFieldMinimumPrimitive(secret.Prime);
            int w_i = NumTheoryUtils.ModPow(w, playerNum, secret.Prime);

            var x_values = new Zp[f_x_y.RowCount];

            for (int i = 0; i < f_x_y.RowCount; i++)
            {
                x_values[i] = new Zp(secret.Prime, NumTheoryUtils.ModPow(w_i, i, secret.Prime));
            }

            var tempArr = f_x_y.Times(new ZpMatrix(x_values, VectorType.Column)).ZpVector;

            return(tempArr);
        }
Beispiel #9
0
        /// <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)
        {
#if NO_COMPUTATION
            // send some dummy shares
            var shares = new Zp[numPlayers];
            for (int i = 0; i < numPlayers; i++)
            {
                shares[i] = new Zp(secret.Prime);
            }
            return(shares);
#else
            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 != null);
            Debug.Assert(sharesArr.Length == numPlayers);
            return(sharesArr);
#endif
        }
Beispiel #10
0
        private void SendVerifications(IEnumerable <ShareMsg <Zp> > recvShares)
        {
            // input stage checking - check that each input is legal
            // each iteration in the loop is a verification of player with ID 'playerToVerify'.
            foreach (var recvShare in recvShares)
            {
                var playerToVerify = recvShare.SenderId;
                var secretPoly     = recvShare.Share as SecretPolynomials;

                // first check if the verified dealer had already been caught as a cheater
                if (BadPlayers.Contains(playerToVerify))
                {
                    // no need to check a cheater player's input
                    sharesForComp.Add(new Zp(Prime, 0));
                    continue;
                }

                /* Step 1 - Verify player 'playerToVerify' input  */

                // Extract the received share from the polynomial you received from player with ID 'playerToVerify'
                // Assume I'm the j-th player. Calculate fj(w^i).
                // first check if you received a proper polynomial.
                var isOrigPolyLegal = IsSecretPolynomialsLegal((SecretPolynomials)secretPoly);

                if (isOrigPolyLegal)
                {
                    var verifList_f_j_w_i = secretPoly.CalculateF_i_xValuesForPlayers(NumParties, Prime);
                    var verifMsgs         = GetVerifShareMessages(verifList_f_j_w_i, playerToVerify, true);
                    Send(verifMsgs);
                }
                else                 // received polynomials are corrupted Send random list and remember to complain
                {
                    // received a corrupted polynomials from player with ID 'playerToVerify'
                    var verifList_f_j_w_i = ZpMatrix.GetRandomMatrix(1, NumParties, Prime).GetMatrixRow(0);

                    var verifMsgs = GetVerifShareMessages(verifList_f_j_w_i, playerToVerify, false);
                    Send(verifMsgs);
                }
            }
        }
Beispiel #11
0
        static void Main(string[] args)
        {
            Console.WriteLine("Started.");
            StaticRandom.Init(seed);

            int quorumSize = 20;
            int degree     = quorumSize / 3;

            var secret      = new Zp(Prime, 3);
            var shareMatrix = ZpMatrix.GetIdentityMatrix(quorumSize, Prime);

            // create the initial shares
            var initalShares = ShamirSharing.Share(secret, quorumSize, degree);

            for (var i = 0; i < quorumSize; i++)
            {
                IList <Zp> reshares = QuorumSharing.CreateReshares(initalShares[i], quorumSize, degree);

                for (var j = 0; j < quorumSize; j++)
                {
                    shareMatrix.SetMatrixCell(j, i, reshares[j]);
                }
            }

            // combine the reshares
            List <Zp> finalShares = new List <Zp>();

            for (var i = 0; i < quorumSize; i++)
            {
                Zp finalShare = QuorumSharing.CombineReshares(shareMatrix.GetMatrixRow(i), quorumSize, Prime);
                finalShares.Add(finalShare);
            }

            // combine the shares
            Zp final = ShamirSharing.Recombine(finalShares, degree, Prime);

            Console.WriteLine(final.Value);
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();
        }
Beispiel #12
0
        /// <summary>
        /// Each party in the new quorum needs to call this with the shares received from the old quorum to calculate its share
        /// </summary>
        public static Zp CombineReshares(IList <Zp> reshares, int newQuorumSize, int prime)
        {
            int oldQuorumSize = reshares.Count;

            if (oldQuorumSize != newQuorumSize)
            {
                throw new System.ArgumentException("Do not support case where quorums are of different sizes");
            }

            // Compute the first row of the inverse Vandermonde matrix
            var vandermonde    = ZpMatrix.GetVandermondeMatrix(oldQuorumSize, newQuorumSize, prime);
            var vandermondeInv = vandermonde.Inverse.GetMatrixColumn(0);

            var S = new Zp(prime);

            for (var i = 0; i < newQuorumSize; i++)
            {
                S += vandermondeInv[i] * reshares[i];
            }

            return(S);
        }
Beispiel #13
0
        /// <summary>
        /// Evaluates the shared secrets of secret with polynom of degree t and numberOfPlayers players.
        /// </summary>
        public static ShareDetails DetailedShare(Zp secret,
                                                 int numPlayers, int polynomDeg)
        {
            if (numPlayers <= polynomDeg)
            {
                throw new ArgumentException("Polynomial degree cannot be bigger or equal to the number of  players");
            }

            // Creating the Random Polynomial - f(x)
            var randomMatrix = ZpMatrix.GetRandomMatrix(1, polynomDeg + 1, secret.Prime);

            // The free variable in the Random Polynomial( f(x) ) is the seceret
            randomMatrix.SetMatrixCell(0, 0, secret);

            // Create vanderMonde matrix
            var vanderMonde = ZpMatrix.GetPrimitiveVandermondeMatrix(polynomDeg + 1, numPlayers, secret.Prime);

            // Compute f(i) for the i-th  player
            var sharesArr = randomMatrix.Times(vanderMonde).ZpVector;

            var details = new ShareDetails(randomMatrix.GetMatrixRow(0), sharesArr);

            return(details);
        }
Beispiel #14
0
        /*
         * Finds a solution to a system of linear equations represtented by an
         * n-by-n+1 matrix A: namely, denoting by B the left n-by-n submatrix of A
         * and by C the last column of A, finds a column vector x such that Bx=C.
         * If more than one solution exists, chooses one arbitrarily by setting some
         * values to 0.  If no solutions exists, returns false.  Otherwise, places
         * a solution into the first argument and returns true.
         *
         * Note : matrix A changes (gets converted to row echelon form).
         */

        private static Zp[] linearSolve(ZpMatrix A, ZpMatrix B, int prime)
        {
            var invArray = NumTheoryUtils.GetFieldInverse(prime);
            var C        = ZpMatrix.GetConcatenationMatrix(A, B);               // augmented matrix
            int n        = C.RowCount;

            int[] solution = new int[n];
            int   temp;

            int firstDeterminedValue = n;

            // we will be determining values of the solution
            // from n-1 down to 0.  At any given time,
            // values from firstDeterminedValue to n-1 have been
            // found. Initializing to n means
            // no values have been found yet.
            // To put it another way, the variabe firstDeterminedValue
            // stores the position of first nonzero entry in the row just examined
            // (except at initialization)

            int rank = C.Gauss();

            int[][] cContent = C.Data;

            // can start at rank-1, because below that are all zeroes
            for (int row = rank - 1; row >= 0; row--)
            {
                // remove all the known variables from the equation
                temp = cContent[row][n];
                int col;
                for (col = n - 1; col >= firstDeterminedValue; col--)
                {
                    temp = Zp.Modulo(temp - (cContent[row][col] * solution[col]), prime);
                }

                // now we need to find the first nonzero coefficient in this row
                // if it exists before firstDeterminedValue
                // because the matrix is in row echelon form, the first nonzero
                // coefficient cannot be before the diagonal
                for (col = row; col < firstDeterminedValue; col++)
                {
                    if (cContent[row][col] != 0)
                    {
                        break;
                    }
                }

                if (col < firstDeterminedValue)                 // this means we found a nonzero coefficient
                {
                    // we can determine the variables in position from col to firstDeterminedValue
                    // if this loop executes even once, then the system is undertermined
                    // we arbitrarily set the undetermined variables to 0, because it make math easier
                    for (int j = col + 1; j < firstDeterminedValue; j++)
                    {
                        solution[j] = 0;
                    }

                    // Now determine the variable at the nonzero coefficient
                    //div(solution[col], temp, A.getContent()[row][col]);
                    solution[col]        = temp * invArray[Zp.Modulo(cContent[row][col], prime)];
                    firstDeterminedValue = col;
                }
                else
                {
                    // this means there are no nonzero coefficients before firstDeterminedValue.
                    // Because we skip all the zero rows at the bottom, the matrix is in
                    // row echelon form, and firstDeterminedValue is equal to the
                    // position of first nonzero entry in row+1 (unless it is equal to n),
                    // this means we are at a row with all zeroes except in column n
                    // The system has no solution.
                    return(null);
                }
            }

            // set the remaining undetermined values, if any, to 0
            for (int col = 0; col < firstDeterminedValue; col++)
            {
                solution[col] = 0;
            }

            var ResultVec = new Zp[n];

            for (int i = 0; i < n; i++)
            {
                ResultVec[i] = new Zp(prime, solution[i]);
            }

            return(ResultVec);
        }
Beispiel #15
0
        /*
        * Finds a solution to a system of linear equations represtented by an
        * n-by-n+1 matrix A: namely, denoting by B the left n-by-n submatrix of A
        * and by C the last column of A, finds a column vector x such that Bx=C.
        * If more than one solution exists, chooses one arbitrarily by setting some
        * values to 0.  If no solutions exists, returns false.  Otherwise, places
        * a solution into the first argument and returns true.
        *
        * Note : matrix A changes (gets converted to row echelon form).
        */
        private static Zp[] linearSolve(ZpMatrix A, ZpMatrix B, int prime)
        {
            var invArray = NumTheoryUtils.GetFieldInverse(prime);
            var C = ZpMatrix.GetConcatenationMatrix(A, B);		// augmented matrix
            int n = C.RowCount;
            int[] solution = new int[n];
            int temp;

            int firstDeterminedValue = n;

            // we will be determining values of the solution
            // from n-1 down to 0.  At any given time,
            // values from firstDeterminedValue to n-1 have been
            // found. Initializing to n means
            // no values have been found yet.
            // To put it another way, the variabe firstDeterminedValue
            // stores the position of first nonzero entry in the row just examined
            // (except at initialization)

            int rank = C.Gauss();

            int[][] cContent = C.Data;

            // can start at rank-1, because below that are all zeroes
            for (int row = rank - 1; row >= 0; row--)
            {
                // remove all the known variables from the equation
                temp = cContent[row][n];
                int col;
                for (col = n - 1; col >= firstDeterminedValue; col--)
                    temp = Zp.Modulo(temp - (cContent[row][col] * solution[col]), prime);

                // now we need to find the first nonzero coefficient in this row
                // if it exists before firstDeterminedValue
                // because the matrix is in row echelon form, the first nonzero
                // coefficient cannot be before the diagonal
                for (col = row; col < firstDeterminedValue; col++)
                {
                    if (cContent[row][col] != 0)
                        break;
                }

                if (col < firstDeterminedValue) // this means we found a nonzero coefficient
                {
                    // we can determine the variables in position from col to firstDeterminedValue
                    // if this loop executes even once, then the system is undertermined
                    // we arbitrarily set the undetermined variables to 0, because it make math easier
                    for (int j = col + 1; j < firstDeterminedValue; j++)
                        solution[j] = 0;

                    // Now determine the variable at the nonzero coefficient
                    //div(solution[col], temp, A.getContent()[row][col]);
                    solution[col] = temp * invArray[Zp.Modulo(cContent[row][col], prime)];
                    firstDeterminedValue = col;
                }
                else
                {
                    // this means there are no nonzero coefficients before firstDeterminedValue.
                    // Because we skip all the zero rows at the bottom, the matrix is in
                    // row echelon form, and firstDeterminedValue is equal to the
                    // position of first nonzero entry in row+1 (unless it is equal to n),
                    // this means we are at a row with all zeroes except in column n
                    // The system has no solution.
                    return null;
                }
            }

            // set the remaining undetermined values, if any, to 0
            for (int col = 0; col < firstDeterminedValue; col++)
                solution[col] = 0;

            var ResultVec = new Zp[n];
            for (int i = 0; i < n; i++)
                ResultVec[i] = new Zp(prime, solution[i]);

            return ResultVec;
        }