Beispiel #1
0
        /// <summary>
        /// Perform a Matrix operation (add / subtract)
        /// </summary>
        /// <param name="sid">Session ID</param>
        /// <param name="operation">Operation to perform</param>
        /// <param name="code">Azure Function key</param>
        private async Task PerformMatrixOperation(string sid, string operation, string code)
        {
            ClearLog();
            Log($"Session ID: {sid}");

            MatrixData mda    = MatrixA.Matrix.DataContext as MatrixData;
            MatrixData mdb    = MatrixB.Matrix.DataContext as MatrixData;
            Plaintext  plaina = Utilities.MatrixToPlaintext(Utilities.MatrixDataToMatrix(mda), encoder_);
            Plaintext  plainb = Utilities.MatrixToPlaintext(Utilities.MatrixDataToMatrix(mdb), encoder_);

            Plaintext plain = await PerformOperation(sid, operation, code, plaina, plainb);

            if (null == plain)
            {
                OperationResult.MatrixTitle = $"Error executing {operation}";
                OperationResult.ClearMatrix();
                return;
            }

            int rows = mda.DataView.Table.Rows.Count;
            int cols = mda.DataView.Table.Columns.Count;

            int[,] matresult = Utilities.PlaintextToMatrix(plain, rows, cols, encoder_);

            OperationResult.MatrixTitle = "Result";
            OperationResult.InitMatrix(matresult);
        }
        /// <summary>
        /// Initialize a MatrixData instance of the appropriate size
        /// </summary>
        /// <param name="rows">Rows in MatrixData</param>
        /// <param name="columns">Columns in MatrixData</param>
        /// <returns>Initialized MatrixData</returns>
        private static MatrixData InitMatrixData(int[,] matrix)
        {
            MatrixData data = new MatrixData();
            int        rows = matrix.GetLength(dimension: 0);
            int        cols = matrix.GetLength(dimension: 1);

            for (int c = 0; c < cols; c++)
            {
                data.DataTable.Columns.Add((c + 1).ToString());
                data.DataTable.Columns[c].DataType    = typeof(int);
                data.DataTable.Columns[c].AllowDBNull = false;
            }

            for (int r = 0; r < rows; r++)
            {
                object[] rowVals = new object[cols];
                for (int c = 0; c < cols; c++)
                {
                    rowVals[c] = matrix[r, c];
                }

                data.DataTable.Rows.Add(rowVals);
            }

            return(data);
        }
        /// <summary>
        /// Initialize data grid with the given matrix
        /// </summary>
        /// <param name="matrix"></param>
        public void InitMatrix(int[,] matrix)
        {
            MatrixData data    = InitMatrixData(matrix);
            MatrixData oldData = DataContext as MatrixData;

            DataContext = data;

            bool matrixChanged = (oldData == null) || (null != oldData &&
                                                       (oldData.DataTable.Rows.Count != data.DataTable.Rows.Count ||
                                                        oldData.DataTable.Columns.Count != data.DataTable.Columns.Count));

            if (matrixChanged)
            {
                MatrixSizeChanged?.Invoke(this, EventArgs.Empty);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Get a Matrix of integers from a MatrixData object
        /// </summary>
        /// <param name="md">MatrixData object to get the matrix from</param>
        /// <returns>Matrix of integers</returns>
        public static int[,] MatrixDataToMatrix(MatrixData md)
        {
            int rows = md.DataView.Table.Rows.Count;
            int cols = md.DataView.Table.Columns.Count;

            int[,] result = new int[rows, cols];
            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < cols; c++)
                {
                    result[r, c] = (int)md.DataView.Table.Rows[r].ItemArray[c];
                }
            }

            return(result);
        }
Beispiel #5
0
        /// <summary>
        /// Perform a Matrix multiplication.
        ///
        /// Please refer to the file MATRIXMULTIPLICATION.md for an explanation of
        /// how matrix multiplication is implemented in this application.
        /// </summary>
        private async Task PerformMatrixMultiplication(string sid, string code)
        {
            ClearLog();
            Log($"Session ID: {sid}");

            // Query RelinKeys with given sid
            if (!await QueryPublicKeys(sid, "RelinKeys", GlobalProperties.Codes.PublicKeysQuery))
            {
                // Upload RelinKeys if needed
                if (!await UploadPublicKeys(
                        sid, GlobalProperties.PublicKeyType.RelinKeys,
                        GlobalProperties.Codes.PublicKeysUpload))
                {
                    Log($"RelinKeys upload failed");
                    return;
                }
            }

            // Query GaloisKeys with given sid
            if (!await QueryPublicKeys(sid, "GaloisKeys", GlobalProperties.Codes.PublicKeysQuery))
            {
                // Upload GaloisKeys if needed
                if (!await UploadPublicKeys(
                        sid, GlobalProperties.PublicKeyType.GaloisKeys,
                        GlobalProperties.Codes.PublicKeysUpload))
                {
                    Log($"GaloisKeys upload failed");
                    return;
                }
            }

            MatrixData mda = MatrixA.Matrix.DataContext as MatrixData;
            MatrixData mdb = MatrixB.Matrix.DataContext as MatrixData;

            int[,] matrixa = Utilities.MatrixDataToMatrix(mda);
            int[,] matrixb = Utilities.MatrixDataToMatrix(mdb);
            int marows = matrixa.GetLength(dimension: 0);
            int macols = matrixa.GetLength(dimension: 1);
            int mbrows = matrixb.GetLength(dimension: 0);
            int mbcols = matrixb.GetLength(dimension: 1);

            if (marows < 1 || macols < 1 || mbrows < 1 || mbcols < 1 || macols != mbrows)
            {
                throw new InvalidOperationException("matrices are incompatible for multiplication");
            }

            bool transposed = false;

            if (Math.Max(mbrows, mbcols) < Math.Max(marows, macols))
            {
                transposed = true;
                Log("Computing on transposes for improved performance");
                (matrixa, matrixb) = (Utilities.Transpose(matrixb), Utilities.Transpose(matrixa));
                (marows, macols, mbrows, mbcols) = (mbcols, mbrows, macols, marows);
            }

            // We use a power of two dimension always
            int dimension = Utilities.FindNextPowerOfTwo((ulong)Math.Max(marows, macols));

            int[,] paddedMatrixa = new int[dimension, dimension];
            for (int r = 0; r < marows; r++)
            {
                for (int c = 0; c < macols; c++)
                {
                    paddedMatrixa[r, c] = matrixa[r, c];
                }
            }

            // Create a matrix whose rows are generalized diagonals of matrix A
            int[,] cyclicDiagsMatrix = new int[dimension, dimension];
            for (int r = 0; r < dimension; r++)
            {
                for (int c = 0; c < dimension; c++)
                {
                    cyclicDiagsMatrix[r, c] = paddedMatrixa[c, (c + r) % dimension];
                }
            }

            // Make cyclicDiagsMatrix into a List of plaintexts
            List <Plaintext> cdmPlains = Utilities.RowsToPlaintexts(cyclicDiagsMatrix, mbcols, encoder_);

            // Make matrixb into row-major set of plaintexts
            int[,] paddedMatrixb = new int[dimension, mbcols];
            for (int r = 0; r < mbrows; r++)
            {
                for (int c = 0; c < mbcols; c++)
                {
                    paddedMatrixb[r, c] = matrixb[r, c];
                }
            }
            Plaintext matrixbPlain = Utilities.MatrixToTwistedPlaintext(paddedMatrixb, encoder_);

            Plaintext plainResult = await PerformMatrixProductOperation(sid, code, cdmPlains, matrixbPlain);

            if (null == plainResult)
            {
                OperationResult.MatrixTitle = "Error performing matrix product";
                OperationResult.ClearMatrix();

                return;
            }

            int[,] wideResult = new int[dimension, mbcols];
            wideResult        = Utilities.PlaintextToMatrix(plainResult, dimension, mbcols, encoder_);

            if (transposed)
            {
                wideResult = Utilities.Transpose(wideResult);
                (marows, macols, mbrows, mbcols) = (mbcols, mbrows, macols, marows);
            }

            int[,] result = new int[marows, mbcols];
            for (int r = 0; r < marows; r++)
            {
                for (int c = 0; c < mbcols; c++)
                {
                    result[r, c] = wideResult[r, c];
                }
            }

            OperationResult.MatrixTitle = "Result";
            OperationResult.InitMatrix(result);
        }