Skip to content

AvivAbramovich/HElib_MatrixOperations

Repository files navigation

Encrypted Matrix Operations using HElib

I implemented encrypted matrices multiplication, and other matrices operations, in the Homomorphic Encryption scheme. I’m using the HElib by Shai Halevi, that implemented Fully Homomorphic Encryption scheme and vector operations like vectors element by element addition, subtraction and multiplication.

The multiplication algorithm described in my “Diagonal Order Matrices Multiplication”, that save the matrix as diagonal vectors, and the multiplication between the vectors, using SIMD operations, returns the result’s diagonal vector. That way of multiplication have some benefits:

It is the fastest way. Works about 10 times faster than the over multiplication algorithms that described in Shai’s “Algorithm in HElib” (The rows order and columns order)

In this algorithm, all the matrices in the same representation type, and no need to “match” the representation type to perform some kind of operations (for example: in Shai’s algorithm, you always need the second matrix in the multiplication to be columns order, and for matrices addition, you need them both to be in the same representation).

Shai’s article “Algorithms in HElib“, that describes how to multiply  matrix by vector, using only vectors operations, like these HElib implementing, and my 

My addition to HElib is classes that handle matrices, vectors and ‘Grid’ matrices, a “big” matrix that divided to grid of smaller matrices. These classes handle the plain text or encrypted data, and provide operations on the matrices or between the matrices, like get specific elements, encrypt a plain-text matrix, decrypt an encrypted matrix, or add/subtract/multiply two matrices/matrix-vector.

Helping Classes

1.1 MatSize

That class is help to provide data about the matrix size, and which operations is legal. This class is needed, because when we encrypt our data in HElib, the vectors size might to change. The Ctxt (an encrypted vector in HElib)  size (referred as nslots) set by various of parameters, and cannot be change to be fit to our data. We need to fit out data to nslots. So if we want to encrypt a vector that it’s size is smaller than nslots, we padding it with zeros to fit, but than we lost the information about the matrix dimensions size. The MatSize object is save the original matrix sizes, and say which operations is legit. for example, multiplication of 100100 matrix with 20100 matrix is not possible, so the multiplication would be aborted (or returned the original matrix in my implementation).

MatSize’s important methods:

MatSize operator*(const MatSize& other) const; //return the size of the multiplication result, or (0,0) if the multiplication is not possible because this.columns != other.rows

bool operator==(const MatSize& other) const;

bool canMultiply(const MatSize& other) const;

2. Matrices Classes

2.1 PTMatrix

This class represents a plain-text matrix, which each element in it is of type long. This class keep the matrix data, that save in Diagonal Order, as describes in Shai’s “Algorithm in HElib”, that means that each vector is a diagonal in the matrix, that starts in the first row of the matrix.

PTMatrix’s important methods:

EncryptedMatrix encrypt(const EncryptedArray&, const FHEPubKey&) const; //Encrypt the matrix

PTMatrix getSubMatrix(unsigned int, unsigned int, MatSize) const;

These methods allow us to encrypt the matrices, or handle the plain-text data.

2.2 EncryptedMatrix

This class represented an encrypted matrix. It holds the encrypted data (as vector of Ctxt’s), and it’s original size as MatSize object.

EncryptedMatrix’s important methods:

PTMatrix decrypt(const EncryptedArray&, const FHESecKey&) const; //decrypt the matrix

EncryptedMatrix operator*(const EncryptedMatrix&) const; //Matrix by matrix multiplication

Ctxt operator*(const Ctxt& vec) const; //matrix multyplication by vector

EncryptedMatrix operator+(const EncryptedMatrix& other) const; //Matrices addition

EncryptedMatrix operator-(const EncryptedMatrix& other) const; //Matrices subtraction

Note:

The first multiplication operator is matrices multiplication, as I described in “Diagonal Order Matrices Multiplication” that returns another EncryptedMatrix. sasasasd The second one is just like Shai’s described in his article, that returns a column vector. That not recommended, because you can’t create with them an EncryptedMatrix object later, and use them with my methods, because it is not diagonal order.

The <. >, <=, >= operators work ONLY when the plain text field is BINARY.

The operator == and != is base on HElib’s operator ==

3. Matrix-Grid Classes

The matrices operations work with classes at 2, but have few limitations/disadvantages, that related to the nslots value:

If we want to encrypt a vector that it’s size is less than nslots, we need to padding it with zeros. Not so horrible, but may cause some problems. For example, when using EncryptedMatrix in DiagonalOrder by Ctxt multiplication, the rotation operation wouldn’t work right, because the extra zeros, and the result might be incorrect.

It bound our matrix size. Say nslots is 100, so we can easily create a 2100 matrix, 100100 matrix,  1,000,000,000100 matrix, but how would we create a 101101 matrix? The answer is we can’t do it in the previous standard way, because 1 of the 2 matrix’s dimensions is bounded by nslots. 

For these reasons, we had to think about a solution that bypass these problems. The first thing we thought to do is try to control that nslots value, but it seems like a really hard work, and it also not so “controllable” because it depends on many parameters.

The second solution, that I implemented here and called it “Matrix-Grid”, is not such an original idea. It says “take the big matrix and break it to a smaller matrices”, creating some grid of matrices, or matrix of matrices. For example, I want to do multiply 2 1M on 1M matrices, but nslots is 100, so I can’t do it with a regular EncryptedMatrix, because it can’t hold any of these 2 matrices, So I break these matrices to a lot 100100 matrices (but could be also 5100 or 200100 if I would like to), so I get a grid in size of 10,00010,000, that each of it “cells” is an EncryptedMatrix, and the multiplication can be preformed as regular matrices multiplication, or any other algorithm. For example, in my implementation, there is a regular matrices multiplication, or Strassen’s Matrix multiplication algorithm (optional).

3.1 PTMatrixGrid

This class represents a plain-text matrix grid as described above. This class hold a vector of vectors of PTMatrix

PTMatrixGrid’s important methods:

PTMatrixGrid(const PTMatrix&, const MatSize); //A constructor that take a “big” PTMatrix, and break it to smaller matrices in the wanted size. using basically the PTMatrix::getSubMatrix method

PTMatrix reunion() const; //do the reverse way, take a grid and “reconstructing” it back to a big PTMatrix

EncryptedMatrixGrid encrypt(const EncryptedArray&, const FHEPubKey&) const; //encrypt the plain text grid

3.2 PTVectorGrid

Really similar to PTMatrix, but for vectors. Not really usefully, unless you want to preform a grid matrix multiplication by vector, and so you have to break that vector to a 1D grid as well.

PTVectorGrid’s important methods:

PTVectorGrid(const vector<long>&, unsigned int); //break the vector to a sub-vectors in the wanted size

EncryptedVectorGrid encrypt(const EncryptedArray&, const FHEPubKey&) const; //encrypt the vector

vector<long> reunion() const; //reconstruct the big vector

3.3 EncryptedMatrixGrid

This class represented an encrypted matrix grid

EncryptedMatrixGrid’s important methods:

PTMatrixGrid decrypt(const EncryptedArray&, const FHESecKey&) const; //decrypt the grid

EncryptedVectorGrid operator*(const EncryptedVectorGrid&) const; //a multiplication by vector-grid

EncryptedMatrixGrid operator*(const EncryptedMatrixGrid& other) const; //multiplication by another EncryptedMatrixGrid

EncryptedMatrixGrid operator+(const EncryptedMatrixGrid& other) const; //adding 2 matrix grids

EncryptedMatrixGrid operator-(const EncryptedMatrixGrid& other) const; //subtraction of 2 matrix grids

void enableStrassenMultiplication(unsigned int limit); //enable using Strassen’s matrices multiplication algorithm with O(n^log7) instead O(n^3). limit is the size the below that, it won’t use the Strassen’s algorithm, but a regular multiplication

void disableStrassenMultiplication(); //disable the Strassen’s algorithm

3.3 EncryptedVectorGrid

Same as EncryptedMatrixGrid but for vector. Usefully for encrypted matrix grid by vector grid multiplication

EncryptedVectorGrid’s important methods:

PTVectorGrid decrypt(const EncryptedArray&, const FHESecKey&) const; //decrypt the grid

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published