Skip to content

Latest commit

 

History

History
158 lines (126 loc) · 6.74 KB

README.md

File metadata and controls

158 lines (126 loc) · 6.74 KB

Example using Intel Paillier Cryptosystem Library

This document provides an example program for using the Intel Paillier Cryptosystem Library in an external application.

Contents

Installation

To install the library,

cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/path/to/install/ -DCMAKE_BUILD_TYPE=Release -DIPCL_TEST=OFF -DIPCL_BENCHMARK=OFF
cmake --build build -j
cmake --build build --target install

If CMAKE_INSTALL_PREFIX is not explicitly set, the library will automatically set to /opt/intel/ipcl by default.

For more details about the build configuration options, please refer to the build instructions provided in the README.md.

Linking and Running Applications

Before proceeding after the library is installed, it is useful to setup an environment variable to point to the installation location.

export IPCL_DIR=/path/to/ipcl/install/

Building with CMake

A more convenient way to use the library is via the find_package functionality in CMake. In your external applications, add the following lines to your CMakeLists.txt.

find_package(IPCL 2.0.0
    HINTS ${IPCL_HINT_DIR}
    REQUIRED)
target_link_libraries(${TARGET} IPCL::ipcl)

If the library is installed globally, IPCL_DIR or IPCL_HINT_DIR flag is not needed. If environment variable IPCL_DIR is set, IPCL_HINT_DIR is not needed as well. Otherwise IPCL_HINT_DIR should be the directory containing IPCLCOnfig.cmake, under ${CMAKE_INSTALL_PREFIX}/lib/cmake/ipcl-2.0.0/

Using Intel Paillier Cryptosystem Library

Key Generation

The public key and private key pair can be generated by using the ipcl::generateKeypair function.

// key.pub_key, key.priv_key
ipcl::KeyPair key = ipcl::generateKeypair(2048, true); // previously ipcl::keyPair
  • Note: With version v2.0.0 and beyond, the key pair struct type has been changed from ipcl::keyPair to ipcl::KeyPair (uppercase K).

Data handling

The library uses a container - ipcl::PlainText for encryption inputs and decryption outputs as well as plaintext HE operations.

ipcl::PlainText Constructor

// construct w/ unsigned int32
uint32_t val1;
ipcl::PlainText pt1(val1);

// construct w/ unsigned int32 vector
std::vector<uint32_t> val2;
ipcl::PlainText pt2(val2);

// construct w/ IPP-Crypto BigNumber
BigNumber val3;
ipcl::PlainText pt3(val3);

// construct w/ IPP-Crypto BigNumber vector
std::vector<BigNumber> val4;
ipcl::PlainText pt4(val4);

For more details about the IPP-Crypto BigNumber class, please refer to Intel IPP Developer Reference.

Accessing data

The library provides several methods to handle and access the data included in the ipcl::PlainText container.

ipcl::PlainText pt(raw_data);

BigNumber ret1 = pt[1]; // idx
std::vector<BigNumber> ret2 = pt; // convert
pt.insert(pos, val); // insert BigNumber to position
pt.remove(pos, length); // remove element (default length=1)
ipcl::PlainText pt_copy = pt; // copy
pt_copy.clear(); // empty the container

FOr more details, please refer to the base_text.hpp and plaintext.hpp.

Encryption and Decryption

The public key is used to encrypt ipcl::PlainText objects for ipcl::CipherText outputs. In the same way, the private key is used to decrypt ipcl::CipherText objects for ipcl::PlainText outputs.

ipcl::PlainText pt(raw_data);
ipcl::CipherText ct = key.pub_key.encrypt(pt); // previously key.pub_key->encrypt(pt)
ipcl::PlainText dec_pt = key.priv_key.decrypt(ct);  // previously key.priv_key->decrypt(ct)
  • Note: With version v2.0.0 and beyond, the keys in ipcl::KeyPair have been changed to be objects, hence the changes from key.pub_key->encrypt(pt) and key.priv_key->decrypt(ct) to key.pub_key.encrypt(pt) and key.priv_key.decrypt(ct), respectively.

HE Operations

Since the Intel Paillier Cryptosystem Library being a partially homomorphic encryption scheme, while addition is supports both ciphertext operands, multiplication only supports single ciphertext operand.

// setup
ipcl::PlainText a, b;

ipcl::CipherText ct_a = key.pub_key.encrypt(a);
ipcl::CipherText ct_b = key.pub_key.encrypt(b);

// Addition (all three end up being same values after decryption)
ipcl::CipherText ct_c1 = ct_a + ct_b; // ciphertext + ciphertext
ipcl::CipherText ct_c2 = ct_a + b; // ciphertext + plaintext
ipcl::CipherText ct_c3 = ct_b + a; // ciphertext + plaintext

// Multiplication
ipcl::CipherText ct_d1 = ct_a * b; // ciphertext * plaintext
ipcl::CipherText ct_d2 = ct_b * a;

Enabling QAT usage

When QAT is enabled while building the library with the flag IPCL_ENABLE_QAT=ON, it is essential to initialize and release the HE QAT context.

// Initialize HE QAT context
ipcl::initializeContext("QAT");

// perform IPCL operations
auto ct = key.pub_key.encrypt(pt);
auto dec_pt = key.priv_key.decrypt(ct);

// Release HE QAT context
ipcl::terminateContext();

If QAT is disabled, ipcl::initializeContext("QAT") statement will not do anything, thus safe to include in any codes using the library.

Hybrid mode configuration

The main accelerated operation - modular exponentiation - can be performed by either IPP-Crypto or the HE QAT. Our library provides a configurable method to distribute the workload between these two methods.

// Use optimal mode
ipcl::setHybridMode(ipcl::HybridMode::OPTIMAL);

// Use IPP-Crypto modexp only
ipcl::setHybridMode(ipcl::HybridMode::IPP);

// Use QAT modexp only
ipcl::setHybridMode(ipcl::HybridMode::QAT);

By default, the hybrid mode is set to ipcl::HybridMode::OPTIMAL. For more details about the modes, please refer to mod_exp.hpp.