Here is a sample code (and its output) of how to use EvalSum, EvalSumRows, and EvalSumCols.
The code assumes you are using CKKS. Note that this code is for illustrative purposes only and does not use standard security parameters.
int main() {
uint32_t multDepth = 1;
uint32_t scaleModSize = 50;
uint32_t N = 16;
uint32_t batchSize = N/2;
CCParams<CryptoContextCKKSRNS> parameters;
parameters.SetMultiplicativeDepth(multDepth);
parameters.SetScalingModSize(scaleModSize);
parameters.SetBatchSize(batchSize);
parameters.SetSecurityLevel(HEStd_NotSet);
parameters.SetRingDim(N);
CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);
// Enable the features that you wish to use
cc->Enable(PKE);
cc->Enable(KEYSWITCH);
cc->Enable(LEVELEDSHE);
cc->Enable(ADVANCEDSHE);
auto keys = cc->KeyGen();
// Encoding and encryption of inputs
// Inputs
std::vector<double> x1 = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.5};
std::vector<double> mat1 = {1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0};
std::vector<double> mat2 = {1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0};
uint32_t rowSize = 4;
// Encoding as plaintexts
Plaintext ptxt1 = cc->MakeCKKSPackedPlaintext(x1);
Plaintext ptxtMat1 = cc->MakeCKKSPackedPlaintext(mat1);
Plaintext ptxtMat2 = cc->MakeCKKSPackedPlaintext(mat2);
std::cout << "Input x1: " << ptxt1 << std::endl;
std::cout << "Input mat1: " << ptxtMat1 << std::endl;
std::cout << "Input mat2: " << ptxtMat2 << std::endl;
// Encrypt the encoded vectors
std::cout << "Encryption\n";
auto c1 = cc->Encrypt(keys.publicKey, ptxt1);
auto ctMat1 = cc->Encrypt(keys.publicKey, ptxtMat1);
auto ctMat2 = cc->Encrypt(keys.publicKey, ptxtMat2);
std::cout << "Generating EvalSum* keys\n";
cc->EvalSumKeyGen(keys.secretKey, keys.publicKey);
auto evalSumRowKeys = cc->EvalSumRowsKeyGen(keys.secretKey, nullptr, rowSize);
auto evalSumColKeys = cc->EvalSumColsKeyGen(keys.secretKey);
// Evaluation
std::cout << "EvalSum\n";
auto ctSum = cc->EvalSum(c1, batchSize);
std::cout << "EvalSumRows\n";
auto ctRowsSum = cc->EvalSumRows(ctMat1, rowSize, *evalSumRowKeys);
std::cout << "EvalSumCols\n";
auto ctColsSum = cc->EvalSumCols(ctMat2, rowSize, *evalSumColKeys);
// Decryption and output
std::cout << "Decryption\n";
Plaintext result;
std::cout.precision(8);
std::cout << std::endl << "Results of homomorphic evaluations: " << std::endl;
// Decrypt
cc->Decrypt(keys.secretKey, c1, &result);
result->SetLength(batchSize);
std::cout << "x1 = " << result;
std::cout << "Estimated precision in bits: " << result->GetLogPrecision() << std::endl;
cc->Decrypt(keys.secretKey, ctSum, &result);
result->SetLength(batchSize);
std::cout << "sum = " << result;
cc->Decrypt(keys.secretKey, ctRowsSum, &result);
result->SetLength(batchSize);
std::cout << "sum Rows: " << result;
cc->Decrypt(keys.secretKey, ctColsSum, &result);
result->SetLength(batchSize);
std::cout << "sum Cols: " << result;
return 0;
}
Output
Input x1: (1, 1, 1, 1, 1, 1, 1, 1.5, ... ); Estimated precision: 50 bits
Input mat1: (1, 1, 1, 1, 2, 2, 2, 2, ... ); Estimated precision: 50 bits
Input mat2: (1, 1, 1, 1, 2, 2, 2, 2, ... ); Estimated precision: 50 bits
Encryption
Generating EvalSum* keys
EvalSum
EvalSumRows
EvalSumCols
Decryption
Results of homomorphic evaluations:
x1 = (1, 1, 1, 1, 1, 1, 1, 1.5, ... ); Estimated precision: 44 bits
Estimated precision in bits: 44
sum = (8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, ... ); Estimated precision: 43 bits
sum Rows: (3, 3, 3, 3, 3, 3, 3, 3, ... ); Estimated precision: 44 bits
sum Cols: (4, 4, 4, 4, 8, 8, 8, 8, ... ); Estimated precision: 44 bits