Procházet zdrojové kódy

Merge pull request #31 from openfheorg/Oliveira_sphinx_docs

Docstrings + Readme
Rener Oliveira před 1 rokem
rodič
revize
8f371711da

+ 4 - 1
.gitignore

@@ -1,3 +1,6 @@
 build/
 .vscode/
-.idea
+.idea
+.png
+.json
+.txt

+ 10 - 1
CMakeLists.txt

@@ -20,6 +20,7 @@ include_directories( ${OpenFHE_INCLUDE}/binfhe )
 # include_directories( ${OpenFHE_Py_SOURCES} )
 include_directories( ${OpenFHE_Py_INCLUDES}/pke )
 include_directories( ${OpenFHE_Py_INCLUDES}/binfhe )
+include_directories( ${OpenFHE_Py_INCLUDES}/docstrings )
 include_directories( ${OpenFHE_Py_INCLUDES} )
 ### add directories for other OpenFHE modules as needed for your project
 
@@ -48,8 +49,16 @@ pybind11_add_module(openfhe
                     src/pke/cryptocontext_wrapper.cpp
                     )
 ### Python installation 
-find_package(Python REQUIRED COMPONENTS Interpreter Development)
+# Allow the user to specify the path to Python executable (if not provided, find it)
+option(PYTHON_EXECUTABLE_PATH "Path to Python executable" "")
 
+if(NOT PYTHON_EXECUTABLE_PATH)
+    # Find Python and its development components
+    find_package(Python REQUIRED COMPONENTS Interpreter Development)
+else()
+    # Set Python_EXECUTABLE to the specified path
+    set(Python_EXECUTABLE "${PYTHON_EXECUTABLE_PATH}")
+endif()
 execute_process(
     COMMAND "${Python_EXECUTABLE}" -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
     OUTPUT_VARIABLE PYTHON_SITE_PACKAGES

+ 54 - 13
README.md

@@ -1,4 +1,4 @@
-# [Work in Progress] Official Python wrapper for OpenFHE
+# Official Python wrapper for OpenFHE
 
 ## Table of Contents
 
@@ -7,7 +7,7 @@
   - [Linux Install](#linux)
     - [Installing the .so: Conda](#conda)
     - [Installing the .so: System](#system-install)
-- [Running Examples](#examples)
+- [Running Examples](#code-examples)
 
 ## Building
 
@@ -15,10 +15,17 @@
 
 Before building, make sure you have the following dependencies installed:
 
-- [CMake](https://cmake.org/)
+- [OpenFHE](https://openfhe-development.readthedocs.io/en/latest/sphinx_rsts/intro/installation/installation.html)
 - [Python 3.6+](https://www.python.org/)
-- [pybind11](https://pybind11.readthedocs.io)
-- [OpenFHE](https://github.com/openfheorg/openfhe-development)
+- [pybind11](https://pybind11.readthedocs.io/en/stable/installing.html)
+
+You can install pybind11 by runnning:
+  
+```bash
+pip install pybind11 // or alternatively, if you use conda:
+conda install -c conda-forge pybind11
+```
+For custom installation or any other issues, please refer to the official pybind documentation in the link above.
 
 ### Linux
 
@@ -32,6 +39,7 @@ make
 ```
 
 At this point the `.so` file has been built. Your exact installation process will depend on your virtual environment.
+Cmake will automatically find the python installation path, if unwanted, you can specify the python path by adding `-DPYTHON_EXECUTABLE_PATH=/path/to/python` to the cmake command.
 
 #### Conda
 
@@ -42,7 +50,19 @@ conda create -n ${ENV_NAME} python=3.{X} anaconda
 where `${ENV_NAME}` should be replaced with the name of your environment, and `{X}` should be replaced with your desired python version. For example you might have `
 conda create -n openfhe_python python=3.9 anaconda`
 
-then run 
+It's recommended to specify the python path to avoid any issues with conda environments.
+To do this, run the following commands:
+
+```bash
+mkdir build
+cd build
+cmake ..  // Or cmake .. -DPYTHON_EXECUTABLE_PATH=$CONDA_PREFIX/bin/python
+make
+```
+
+The CONDA_PREFIX variable is set by conda, and points to the root of your active conda environment.
+
+Then, you can develop the library:
 
 ```
 mkdir lib
@@ -60,11 +80,32 @@ which creates a lib folder, moves the built `.so` file into that lib folder, and
 make install  // You may have to run sudo make install
 ```
 
-## Examples
-
-After that, you can run the examples in the src/pke/examples folder:
-
-```bash
-python src/pke/examples/simple-integers.py
-```
+## Code Examples
+
+To get familiar with the OpenFHE Python API, check out the examples:
+
+- FHE for arithmetic over integers (BFV):
+  - [Simple Code Example](src/pke/examples/simple-integers.py)
+  <!-- - [Simple Code Example with Serialization](src/pke/examples/simple-integers-serial.py) -->
+- FHE for arithmetic over integers (BGV):
+  - [Simple Code Example](src/pke/examples/simple-integers-bgvrns.py)
+  <!-- - [Simple Code Example with Serialization](src/pke/examples/simple-integers-serial-bgvrns.py) -->
+- FHE for arithmetic over real numbers (CKKS):
+  - [Simple Code Example](src/pke/examples/simple-real-numbers.py)
+  - [Advanced Code Example](src/pke/examples/advanced-real-numbers.py)
+  - [Advanced Code Example for High-Precision CKKS](src/pke/examples/advanced-real-numbers-128.py)
+  - [Arbitrary Smooth Function Evaluation](src/pke/examples/function-evaluation.py)
+  - [Simple CKKS Bootstrapping Example](src/pke/examples/simple-ckks-bootstrapping.py)
+  - [Advanced CKKS Bootstrapping Example](src/pke/examples/advanced-ckks-bootstrapping.cpp)
+  - [Double-Precision (Iterative) Bootstrapping Example](src/pke/examples/iterative-ckks-bootstrapping.py)
+- FHE for Boolean circuits and larger plaintext spaces (FHEW/TFHE):
+  - [Simple Code Example](src/binfhe/examples/boolean.py)
+  - [Truth Table Example](src/binfhe/examples/boolean-truth-table.py)
+  <!-- - [Code with JSON serialization](src/binfhe/examples/boolean-serial-json.py) -->
+  <!-- - [Code with Binary Serialization](src/binfhe/examples/boolean-serial-binary.py) -->
+  <!-- - [Large-Precision Comparison](src/binfhe/examples/eval-sign.py) -->
+  <!-- - [Small-Precison Arbitrary Function Evaluation](src/binfhe/examples/eval-function.py) -->
+<!-- - Threshold FHE:
+  - [Code Example for BGV, BFV, and CKKS](src/pke/examples/threshold-fhe.py)
+  - [Code Example for BFV with 5 parties](src/pke/examples/threshold-fhe-5p.py) -->
 

+ 91 - 0
include/docstrings/binfhecontext_docs.h

@@ -0,0 +1,91 @@
+#ifndef BINFHECONTEXT_DOCSTRINGS_H
+#define BINFHECONTEXT_DOCSTRINGS_H
+
+// BinFHEContext Docs:
+const char* binfhe_GenerateBinFHEContext_parset_docs = R"doc(
+    Creates a crypto context using predefined parameters sets. Recommended for most users.
+
+    Parameters:
+    ----------
+        set (BINFHE_PARAMSET): the parameter set: TOY, MEDIUM, STD128, STD192, STD256.
+        method (BINFHE_METHOD):  the bootstrapping method (DM or CGGI).
+
+    Returns:
+    --------
+        create the crypto context
+)doc";
+
+const char* binfhe_KeyGen_docs = R"doc(
+    Generates a secret key for the main LWE scheme
+
+    Returns:
+    --------
+        LWEPrivateKey: the secret key
+)doc";
+
+const char* binfhe_BTKeyGen_docs = R"doc(
+    Generates bootstrapping keys
+
+    Psrameters:
+    -----------
+        sk (LWEPrivateKey): secret key
+)doc";
+
+const char* binfhe_Encrypt_docs = R"doc(
+    Encrypts a bit using a secret key (symmetric key encryption)
+
+    Parameters:
+    -----------
+        sk (LWEPrivateKey): the secret key
+        m (int): the plaintext
+        output (BINFHE_OUTPUT):  FRESH to generate fresh ciphertext, BOOTSTRAPPED to generate a refreshed ciphertext (default)
+        p (int): plaintext modulus (default 4)
+        mod (int): Encrypt according to mod instead of m_q if mod != 0
+
+    Returns:
+    --------
+        LWECiphertext: the ciphertext
+)doc";
+
+const char* binfhe_Decrypt_docs = R"doc(
+    Encrypt according to mod instead of m_q if mod != 0
+
+    Parameters:
+    -----------
+        sk (LWEPrivateKey): the secret key
+        ct (LWECiphertext): the ciphertext
+        p (int): plaintext modulus (default 4)
+
+    Returns:
+    --------
+       int: the plaintext
+)doc";
+
+const char* binfhe_EvalBinGate_docs = R"doc(
+    Evaluates a binary gate (calls bootstrapping as a subroutine)
+
+    Parameters:
+    -----------
+        gate (BINGATE): the gate; can be AND, OR, NAND, NOR, XOR, or XNOR
+        ct1 (LWECiphertext): first ciphertext
+        ct2 (LWECiphertext): second ciphertext
+
+    Returns:
+    --------
+        LWECiphertext: the resulting ciphertext
+)doc";
+
+const char* binfhe_EvalNOT_docs = R"doc(
+    Evaluates NOT gate
+
+    Parameters:
+    -----------
+        ct (LWECiphertext): the input ciphertext
+
+    Returns:
+    --------
+        LWECiphertext: the resulting ciphertext
+)doc";
+
+
+#endif // BINFHECONTEXT_DOCSTRINGS_H

+ 19 - 0
include/docstrings/ciphertext_docs.h

@@ -0,0 +1,19 @@
+#ifndef CIPHERTEXT_DOCSTRINGS_H
+#define CIPHERTEXT_DOCSTRINGS_H
+
+const char* ctx_GetLevel_docs = R"doc(
+    Get the number of scalings performed
+
+    Returns
+    -------
+        int: The level of the ciphertext.
+)doc";
+
+const char* ctx_SetLevel_docs = R"doc(
+    Set the number of scalings
+
+    Parameters
+    ----------
+        level (int): The level to set.
+)doc";
+#endif // CIPHERTEXT_DOCSTRINGS_H

+ 1184 - 0
include/docstrings/cryptocontext_docs.h

@@ -0,0 +1,1184 @@
+#ifndef CRYPTOCONTEXT_DOCSTRINGS_H
+#define CRYPTOCONTEXT_DOCSTRINGS_H
+
+const char* cc_SetKeyGenLevel_docs = R"doc(
+    Parameters:
+    ----------
+        level (int): the level to set the key generation to
+)doc";
+
+const char* cc_GetKeyGenLevel_docs = R"doc(
+    Get the level used for key generation
+
+    Returns:
+        int: The level used for key generation
+)doc";
+
+const char* cc_GetRingDimension_docs = R"doc(
+    Get the ring dimension used for this context
+
+    Returns:
+        int: The ring dimension
+)doc";
+
+const char* cc_Enable_docs = R"doc(
+    Enable a particular feature for use with this CryptoContext
+
+    Parameters:
+    ----------
+        feature (PKESchemeFeature): the feature that should be enabled. 
+            The list of available features is defined in the PKESchemeFeature enum.
+    
+)doc";
+
+const char* cc_KeyGen_docs = R"doc(
+    Generate a public and private key pair
+
+    Returns:
+        KeyPair: a public/secret key pair
+)doc";
+
+const char* cc_EvalMultKeyGen_docs = R"doc(
+    EvalMultKeyGen creates a key that can be used with the OpenFHE EvalMult operator the new evaluation key is stored in cryptocontext.
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): the private key
+)doc";
+
+const char* cc_EvalMultKeysGen_docs = R"doc(
+    EvalMultsKeyGen creates a vector evalmult keys that can be used with the OpenFHE EvalMult operator 1st key (for s^2) is used for multiplication of ciphertexts of depth 1 2nd key (for s^3) is used for multiplication of ciphertexts of depth 2, etc. a vector of new evaluation keys is stored in crytpocontext
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): the private key
+)doc";
+
+const char* cc_EvalRotateKeyGen_docs = R"doc(
+    EvalRotateKeyGen generates evaluation keys for a list of indices
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): private key
+        indexList (list): list of (integers) indices
+        publicKey (PublicKey): public key (used in NTRU schemes)
+)doc";
+
+// MakeStringPlaintext
+const char* cc_MakeStringPlaintext_docs = R"doc(
+    MakeStringPlaintext constructs a StringEncoding in this context
+
+    Parameters:
+    ----------
+        str (str): the string to convert
+
+    Returns:
+    ----------
+        Plaintext: plaintext
+)doc";
+
+//MakePackedPlaintext
+const char* cc_MakePackedPlaintext_docs = R"doc(
+    MakePackedPlaintext constructs a PackedEncoding in this context
+
+    Parameters:
+    ----------
+        value (list): the vector (of integers) to convert
+        depth (int): is the multiplicative depth to encode the plaintext at
+        level (int): is the level to encode the plaintext at
+
+    Returns:
+    ----------
+        Plaintext: plaintext
+)doc";
+
+//inline Plaintext MakeCoefPackedPlaintext(const std::vector<int64_t> &value, size_t depth = 1, uint32_t level = 0) const
+const char* cc_MakeCoefPackedPlaintext_docs = R"doc(
+    MakeCoefPackedPlaintext constructs a CoefPackedEncoding in this context
+
+    Parameters:
+    ----------
+        value (list): the vector (of integers) to convert
+        depth (int): is the multiplicative depth to encode the plaintext at
+        level (int): is the level to encode the plaintext at
+
+    Returns:
+    ----------
+        Plaintext: plaintext
+)doc";
+//MakeCKKSPackedPlaintext(const std::vector<std::complex<double>> &value, size_t depth = 1, uint32_t level = 0, const std::shared_ptr<ParmType> params = nullptr, usint slots = 0)
+const char* cc_MakeCKKSPackedPlaintextComplex_docs = R"doc(
+    COMPLEX ARITHMETIC IS NOT AVAILABLE STARTING WITH OPENFHE 1.10.6, AND THIS METHOD BE DEPRECATED. USE THE REAL-NUMBER METHOD INSTEAD. MakeCKKSPackedPlaintext constructs a CKKSPackedEncoding in this context from a vector of complex numbers
+
+    Parameters:
+    ----------
+        value (list): input vector (of complex numbers)
+        depth (int): depth used to encode the vector
+        level (int): level at each the vector will get encrypted
+        params (openfhe.ParmType): parameters to be used for the ciphertext (Only accepting params = None in this version)
+        slots (int): number of slots
+
+    Returns:
+    ----------
+        Plaintext: plaintext
+)doc";
+
+//MakeCKKSPlaintextReal
+const char* cc_MakeCKKSPlaintextReal_docs = R"doc(
+    MakeCKKSPlaintext constructs a CKKSPackedEncoding in this context from a vector of real numbers
+
+    Parameters:
+    ----------
+        value (list): input vector (of floats)
+        depth (int): depth used to encode the vector
+        level (int): level at each the vector will get encrypted
+        params (openfhe.ParmType): parameters to be used for the ciphertext (Only accepting params = None in this version)
+        slots (int): number of slots
+
+    Returns:
+    ----------
+        Plaintext: plaintext
+)doc";
+
+//EvalRotate
+const char* cc_EvalRotate_docs = R"doc(
+    EvalRotate rotates a ciphertext by a given index
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): the ciphertext to rotate
+        index (int): the index of the rotation. Positive indices correspond to left rotations and negative indices correspond to right rotations.
+
+    Returns:
+    ----------
+        Ciphertext: the rotated ciphertext
+)doc";
+
+//EvalFastRotationPreCompute
+const char* cc_EvalFastRotationPreCompute_docs = R"doc(
+    EvalFastRotationPrecompute implements the precomputation step of hoisted automorphisms.
+
+    Please refer to Section 5 of Halevi and Shoup, "Faster Homomorphic
+    linear transformations in HELib." for more details, link:
+    https://eprint.iacr.org/2018/244.
+
+    Generally, automorphisms are performed with three steps:
+    (1) The automorphism is applied to the ciphertext.
+    (2) The automorphed values are decomposed into digits.
+    (3) Key switching is applied to enable further computations on the ciphertext.
+
+    Hoisted automorphisms are a technique that performs the digit decomposition for the original ciphertext first,
+    and then performs the automorphism and the key switching on the decomposed digits.
+    The benefit of this is that the digit decomposition is independent of the automorphism rotation index,
+    so it can be reused for multiple different indices.
+    This can greatly improve performance when we have to compute many automorphisms on the same ciphertext.
+    This routinely happens when we do permutations (EvalPermute).
+
+    EvalFastRotationPrecompute implements the digit decomposition step of hoisted automorphisms.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): the input ciphertext on which to do the precomputation (digit decomposition)
+
+    Returns:
+    ----------
+        Ciphertext: the precomputed ciphertext created using the digit decomposition
+)doc";
+
+//EvalFastRotation
+const char* cc_EvalFastRotation_docs = R"doc(
+    EvalFastRotation implements the automorphism and key switching step of hoisted automorphisms.
+
+    Please refer to Section 5 of Halevi and Shoup, "Faster Homomorphic
+    linear transformations in HELib." for more details, link:
+    https://eprint.iacr.org/2018/244.
+
+    Generally, automorphisms are performed with three steps:
+    (1) The automorphism is applied to the ciphertext.
+    (2) The automorphed values are decomposed into digits.
+    (3) Key switching is applied to enable further computations on the ciphertext.
+
+    Hoisted automorphisms are a technique that performs the digit decomposition for the original ciphertext first,
+    and then performs the automorphism and the key switching on the decomposed digits.
+    The benefit of this is that the digit decomposition is independent of the automorphism rotation index,
+    so it can be reused for multiple different indices.
+    This can greatly improve performance when we have to compute many automorphisms on the same ciphertext.
+    This routinely happens when we do permutations (EvalPermute).
+
+    EvalFastRotation implements the automorphism and key switching step of hoisted automorphisms.
+
+    This method assumes that all required rotation keys exist.
+    This may not be true if we are using baby-step/giant-step key switching.
+    Please refer to Section 5.1 of the above reference and EvalPermuteBGStepHoisted to see how to deal with this issue.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext):  the input ciphertext to perform the automorphism on
+        index (int): the index of the rotation. Positive indices correspond to left rotations and negative indices correspond to right rotations.
+        m (int): is the cyclotomic order
+        digits (Ciphertext): the precomputed ciphertext created by EvalFastRotationPrecompute using the digit decomposition at the precomputation step
+)doc";
+
+//EvalFastRotationExt
+const char* cc_EvalFastRotationExt_docs = R"doc(
+    Only supported for hybrid key switching. Performs fast (hoisted) rotation and returns the results in the extended CRT basis P*Q
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        index (int): the rotation index
+        digits (Ciphertext): the precomputed ciphertext created by EvalFastRotationPrecompute
+        addFirst (bool): if true, the the first element c0 is also computed (otherwise ignored)
+    
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+//phertext<Element> EvalAtIndex(ConstCiphertext<Element> ciphertext, int32_t index) const
+const char* cc_EvalAtIndex_docs = R"doc(
+    Moves i-th slot to slot 0
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): the ciphertext
+        i (int): the index
+    
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+//void EvalAtIndexKeyGen(const PrivateKey<Element> privateKey, const std::vector<int32_t> &indexList, const PublicKey<Element> publicKey = nullptr)
+const char* cc_EvalAtIndexKeyGen_docs = R"doc(
+    EvalAtIndexKeyGen generates evaluation keys for a list of indices
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): the private key
+        indexList (list): list of indices
+        publicKey (PublicKey): the public key (used in NTRU schemes)
+    
+    Returns:
+    ----------
+        None
+)doc";
+
+//Encrypt
+const char* cc_Encrypt_docs = R"doc(
+    Encrypt a plaintext using a given public key
+
+    Parameters:
+    ----------
+        plaintext (Plaintext): the plaintext to encrypt
+        publicKey (PublicKey): the public key
+
+    Returns:
+    ----------
+        Ciphertext: ciphertext (or null on failure)
+)doc";
+
+//Decrypt
+const char* cc_Decrypt_docs = R"doc(
+    Decrypt a single ciphertext into the appropriate plaintext
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): ciphertext to decrypt
+        privateKey (PrivateKey): decryption key
+
+    Returns:
+    ----------
+        Plaintext: decrypted plaintext
+)doc";
+
+//EvalAdd
+const char* cc_EvalAdd_docs = R"doc(
+    Add two ciphertexts
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first ciphertext
+        ct2 (Ciphertext): second ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+
+//EvalAdd(ciphertext,double)
+const char* cc_EvalAddfloat_docs = R"doc(
+    EvalAdd - OpenFHE EvalAdd method for a ciphertext and constant
+
+    Parameters:
+    ----------
+        ct (Ciphertext): ciphertext
+        constant (float): constant to add
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext + constant
+)doc";
+
+//EvalAddInPlace
+const char* cc_EvalAddInPlace_docs = R"doc(
+    EvalAdd - OpenFHE EvalAddInPlace method for a pair of ciphertexts
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): Input/output ciphertext
+        ct2 (Ciphertext): Input cipherext
+
+    Returns:
+    ----------
+        ct1 contains ct1 + ct2
+)doc";
+
+//EvalAddInPlace(ciphertext,plaintext)
+const char* cc_EvalAddInPlacePlaintext_docs = R"doc(
+    EvalAdd - OpenFHE EvalAddInPlace method for a ciphertext and plaintext
+
+    Parameters:
+    ----------
+        ct (Ciphertext): Input/output ciphertext
+        pt (Plaintext): Input plaintext
+
+    Returns:
+    ----------
+        ct contains ct + pt
+)doc";
+
+//EvalAddMutable
+const char* cc_EvalAddMutable_docs = R"doc(
+    EvalAdd - OpenFHE EvalAddMutable method for a pair of ciphertexts. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first ciphertext
+        ct2 (Ciphertext): second ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct1 + ct2
+)doc";
+
+//EvalAddMutable(ciphertext,plaintext)
+const char* cc_EvalAddMutablePlaintext_docs = R"doc(
+    EvalAdd - OpenFHE EvalAddMutable method for a ciphertext and plaintext. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): ciphertext
+        plaintext (Plaintext): plaintext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext + plaintext
+)doc";
+
+//EvalAddMutableInPlace
+const char* cc_EvalAddMutableInPlace_docs = R"doc(
+    EvalAdd - Inplace version of EvalAddMutable
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): Input/output ciphertext
+        ct2 (Ciphertext): Input cipherext
+
+    Returns:
+    ----------
+        ct1 contains ct1 + ct2
+)doc";
+
+//EvalSub
+const char* cc_EvalSub_docs = R"doc(
+    EvalSub - OpenFHE EvalSub method for a pair of ciphertexts
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first ciphertext
+        ct2 (Ciphertext): second ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct1 - ct2
+)doc";
+
+//EvalSub(ciphertext,double)
+const char* cc_EvalSubfloat_docs = R"doc(
+    EvalSub - OpenFHE EvalSub method for a ciphertext and constant
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): ciphertext
+        constant (float): constant to subtract
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext - constant
+)doc";
+
+//EvalSub(ciphertext,plaintext)
+const char* cc_EvalSubPlaintext_docs = R"doc(
+    EvalSub - OpenFHE EvalSub method for a ciphertext and plaintext
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): ciphertext
+        plaintext (Plaintext): plaintext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext - plaintext
+)doc";
+
+//EvalSubInPlace
+const char* cc_EvalSubInPlace_docs = R"doc(
+    Inplace version of EvalSub for a pair of ciphertexts
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): Input/output ciphertext
+        ct2 (Ciphertext): Input cipherext
+
+    Returns:
+    ----------
+        ct1 contains ct1 - ct2
+)doc";
+
+//EvalSubInPlace(ciphertext,double)
+const char* cc_EvalSubInPlacefloat_docs = R"doc(
+    Inplace version of EvalSub for a ciphertext and constant
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): Input/output ciphertext
+        constant (float): constant to subtract
+
+    Returns:
+    ----------
+        ciphertext contains ciphertext - constant
+)doc";
+
+//EvalSubMutable
+const char* cc_EvalSubMutable_docs = R"doc(
+    EvalSub - OpenFHE EvalSubMutable method for a pair of ciphertexts. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first ciphertext
+        ct2 (Ciphertext): second ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct1 - ct2
+)doc";
+
+const char* cc_EvalSubMutableInPlace_docs = R"doc(
+    EvalSub - Inplace variant for EvalSubMutable
+)doc";
+//EvalSubMutable(ciphertext,plaintext)
+const char* cc_EvalSubMutablePlaintext_docs = R"doc(
+    EvalSub - OpenFHE EvalSubMutable method for a ciphertext and plaintext. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): 
+        plaintext (Plaintext): 
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext - plaintext
+)doc";
+
+//EvalMult
+const char* cc_EvalMult_docs = R"doc(
+    EvalMult - OpenFHE EvalMult method for a pair of ciphertexts - with key switching
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first ciphertext
+        ct2 (Ciphertext): second ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct1 * ct2
+)doc";
+
+//EvalMult(ciphertext,double)
+const char* cc_EvalMultfloat_docs = R"doc(
+    EvalMult - OpenFHE EvalMult method for a ciphertext and constant
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): the ciphertext
+        constant (float): constant to multiply
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext * constant
+)doc";
+
+//EvalMult(ciphertext,plaintext)
+const char* cc_EvalMultPlaintext_docs = R"doc(
+    EvalMult - OpenFHE EvalMult method for a ciphertext and plaintext
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): the ciphertext
+        plaintext (Plaintext): the plaintext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext * plaintext
+)doc";
+
+//EvalMultMutable
+const char* cc_EvalMultMutable_docs = R"doc(
+    EvalMult - OpenFHE EvalMultMutable method for a pair of ciphertexts. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first ciphertext
+        ct2 (Ciphertext): second ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct1 * ct2
+)doc";
+
+//EvalMultMutable(ciphertext,plaintext)
+const char* cc_EvalMultMutablePlaintext_docs = R"doc(
+    EvalMult - OpenFHE EvalMultMutable method for a ciphertext and plaintext. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): the ciphertext
+        plaintext (Plaintext): the plaintext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ciphertext * plaintext
+)doc";
+
+//EvalMultMutableInPlace
+const char* cc_EvalMultMutableInPlace_docs = R"doc(
+    EvalMult - OpenFHE EvalMult method for a pair of ciphertexts - with key switching This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): Input/output ciphertext
+        ct2 (Ciphertext): Input cipherext
+
+    Returns:
+    ----------
+        ct1 contains ct1 * ct2
+)doc";
+
+//EvalSquare
+const char* cc_EvalSquare_docs = R"doc(
+    EvalSquare - OpenFHE EvalSquare method for a ciphertext
+
+    Parameters:
+    ----------
+        ct (Ciphertext): the ciphertext to square
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct^2 = ct * ct
+)doc";
+
+//EvalSquareMutable
+const char* cc_EvalSquareMutable_docs = R"doc(
+    EvalSquare - OpenFHE EvalSquareMutable method for a ciphertext. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ct (Ciphertext): the ciphertext to square
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct^2 = ct * ct
+)doc";
+
+//EvalSquareInPlace
+const char* cc_EvalSquareInPlace_docs = R"doc(
+    EvalSquare - OpenFHE EvalSquare method for a ciphertext. This is a mutable version - input ciphertexts may get automatically rescaled, or level-reduced.
+
+    Parameters:
+    ----------
+        ct (Ciphertext): Input/output ciphertext
+
+    Returns:
+    ----------
+        ct contains ct^2 = ct * ct
+)doc";
+
+//EvalMultNoRelin
+const char* cc_EvalMultNoRelin_docs = R"doc(
+    EvalMultNoRelin - OpenFHE EvalMult method for a pair of ciphertexts - no key switching (relinearization)
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first ciphertext
+        ct2 (Ciphertext): second ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext for ct1 * ct2
+)doc";
+
+//Relinearize
+const char* cc_Relinearize_docs = R"doc(
+    Function for relinearization of a ciphertext.
+
+    Parameters:
+    ----------
+        ct (Ciphertext): input ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: relienarized ciphertext
+)doc";
+
+//RelinearizeInPlace
+const char* cc_RelinearizeInPlace_docs = R"doc(
+    Function for inplace relinearization of a ciphertext.
+
+    Parameters:
+    ----------
+        ct (Ciphertext): input/output ciphertext
+
+    Returns:
+    ----------
+        ct contains relienarized ciphertext
+)doc";
+
+//EvalMultAndRelinearize
+const char* cc_EvalMultAndRelinearize_docs = R"doc(
+    Function for evaluating multiplication on ciphertext followed by relinearization operation. Currently it assumes that the input arguments have total depth smaller than the supported depth. Otherwise, it throws an error
+
+    Parameters:
+    ----------
+        ct1 (Ciphertext): first input ciphertext
+        ct2 (Ciphertext): second input ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext
+)doc";
+
+//EvalNegate
+const char* cc_EvalNegate_docs = R"doc(
+    EvalSub - OpenFHE Negate method for a ciphertext
+
+    Parameters:
+    ----------
+        ct (Ciphertext): input ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: new ciphertext -ct
+)doc";
+
+//EvalNegateInPlace
+const char* cc_EvalNegateInPlace_docs = R"doc(
+    EvalSub - Inplace OpenFHE Negate method for a ciphertext
+
+    Parameters:
+    ----------
+        ct (Ciphertext): input/output ciphertext
+
+    Returns:
+    ----------
+        ct contains -ct
+)doc";
+
+//EvalLogistic((ConstCiphertext<Element> ciphertext, double a, double b, uint32_t degree)
+// const char* cc_EvalLogistic_docs = R"doc(
+//     Evaluate approximate logistic function 1/(1 + exp(-x)) on a ciphertext using the Chebyshev approximation.
+
+//     Parameters:
+//     ----------
+//         ciphertext (Ciphertext): input ciphertext
+//         a (float): lower bound of argument for which the coefficients were found
+//         b (float): upper bound of argument for which the coefficients were found
+//         degree (int): Desired degree of approximation
+
+//     Returns:
+//     ----------
+//         Ciphertext: the result of polynomial evaluation
+// )doc";
+
+//EvalChebyshevSeries(ConstCiphertext<Element> ciphertext, const std::vector<double> &coefficients, double a, double b)
+const char* cc_EvalChebyshevSeries_docs = R"doc(
+    Method for evaluating Chebyshev polynomial interpolation; first the range [a,b] is mapped to [-1,1] using linear transformation 1 + 2 (x-a)/(b-a) If the degree of the polynomial is less than 5, use EvalChebyshevSeriesLinear, otherwise, use EvalChebyshevSeriesPS.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        coefficients (list): is the list of coefficients in Chebyshev expansion
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation
+)doc";
+
+//EvalChebyshevSeriesLinear(ConstCiphertext<Element> ciphertext, const std::vector<double> &coefficients, double a, double b)
+const char* cc_EvalChebyshevSeriesLinear_docs = R"doc(
+    Evaluate Chebyshev polynomial of degree less than 5.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        coefficients (list): is the list of coefficients in Chebyshev expansion
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation
+)doc";
+
+//EvalChebyshevSeriesPS(ConstCiphertext<Element> ciphertext, const std::vector<double> &coefficients, double a, double b)
+const char* cc_EvalChebyshevSeriesPS_docs = R"doc(
+    Evaluate Chebyshev polynomial of degree greater or equal to 5.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        coefficients (list): is the list of coefficients in Chebyshev expansion
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation
+)doc";
+
+//EvalChebyshevFunction(std::function<double(double)> func, ConstCiphertext<Element> ciphertext, double a, double b, uint32_t degree)
+const char* cc_EvalChebyshevFunction_docs = R"doc(
+    Method for calculating Chebyshev evaluation on a ciphertext for a smooth input function over the range [a,b].
+
+    Parameters:
+    ----------
+        func (function): is the function to be approximated
+        ciphertext (Ciphertext): input ciphertext
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+        degree (int): Desired degree of approximation
+
+    Returns:
+    ----------
+        Ciphertext: the coefficients of the Chebyshev approximation.
+)doc";
+
+//EvanSin(ciphertext,double,double,degree)
+const char* cc_EvalSin_docs = R"doc(
+    Evaluate approximate sine function on a ciphertext using the Chebyshev approximation.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+        degree (int): Desired degree of approximation
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation.
+)doc";
+
+//EvalCos(ciphertext,double,double,degree)
+const char* cc_EvalCos_docs = R"doc(
+    Evaluate approximate cosine function on a ciphertext using the Chebyshev approximation.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+        degree (int): Desired degree of approximation
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation.
+)doc";
+
+//EvalLogistic(ciphertext,double,double,degree)
+const char* cc_EvalLogistic_docs = R"doc(
+    Evaluate approximate logistic function 1/(1 + exp(-x)) on a ciphertext using the Chebyshev approximation.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+        degree (int): Desired degree of approximation
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation.
+)doc";
+
+//EvalDivide(ciphertext,double,double,degree)
+const char* cc_EvalDivide_docs = R"doc(
+    Evaluate approximate division function 1/x where x >= 1 on a ciphertext using the Chebyshev approximation.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        a (float): lower bound of argument for which the coefficients were found
+        b (float): upper bound of argument for which the coefficients were found
+        degree (int): Desired degree of approximation
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation.
+)doc";
+
+//EvalSumKeyGen(const PrivateKey<Element> privateKey, const PublicKey<Element> publicKey = nullptr)
+const char* cc_EvalSumKeyGen_docs = R"doc(
+    EvalSumKeyGen generates the key map to be used by evalsum
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): private key
+        publicKey (PublicKey): public key (used in NTRU schemes)
+    
+    Returns:
+    ----------
+        None
+)doc";
+
+//EvalSumRowsKeyGen(const PrivateKey<Element> privateKey, const PublicKey<Element> publicKey = nullptr, usint rowSize = 0, usint subringDim = 0)
+const char* cc_EvalSumRowsKeyGen_docs = R"doc(
+    EvalSumRowsKeyGen generates the key map to be used by EvalSumRows
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): private key
+        publicKey (PublicKey): public key (used in NTRU schemes)
+        rowSize (int): number of rows
+        subringDim (int): dimension of the subring
+    
+    Returns:
+    ----------
+        dict: Evaluation key map, where the keys being integer indexes and values being EvalKey objects
+)doc";
+
+//EvalSumColsKeyGen(const PrivateKey<Element> privateKey, const PublicKey<Element> publicKey = nullptr)
+const char* cc_EvalSumColsKeyGen_docs = R"doc(
+    EvalSumColsKeyGen generates the key map to be used by EvalSumCols
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): private key
+        publicKey (PublicKey): public key (used in NTRU schemes)
+    
+    Returns:
+    ----------
+        dict: Evaluation key map, where the keys being integer indexes and values being EvalKey objects
+)doc";
+
+//Ciphertext<Element> EvalSumRows(ConstCiphertext<Element> ciphertext, usint rowSize, const std::map<usint, EvalKey<Element>> &evalSumKeyMap, usint subringDim = 0)
+const char* cc_EvalSumRows_docs = R"doc(
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        rowSize (int): number of rows
+        evalSumKeyMap (dict): evaluation key map, where the keys being integer indexes and values being EvalKey objects
+        subringDim (int): dimension of the subring
+    
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+
+//Ciphertext<Element> EvalSumCols(ConstCiphertext<Element> ciphertext, usint rowSize, const std::map<usint, EvalKey<Element>> &evalSumKeyMap
+const char* cc_EvalSumCols_docs = R"doc(
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        rowSize (int): number of rows
+        evalSumKeyMap (dict): evaluation key map, where the keys being integer indexes and values being EvalKey objects
+    
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+//EvalInnerProduct(ciphertext,ciphertext,batchSize)
+const char* cc_EvalInnerProduct_docs = R"doc(
+    Evaluates inner product in batched encoding
+
+    Parameters:
+    ----------
+        ciphertext1 (Ciphertext): first vector
+        ciphertext2 (Ciphertext): second vector
+        batchSize (int): size of the batch to be summed up
+
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+
+//EvalInnerProduct(cipher,plain,batchsize)
+const char* cc_EvalInnerProductPlaintext_docs = R"doc(
+    Evaluates inner product in batched encoding
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): first vector - ciphertext
+        plaintext (Plaintext): second vector - plaintext
+        batchSize (int): size of the batch to be summed up
+
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+
+//Ciphertext<Element> EvalMerge(const std::vector<Ciphertext<Element>> &ciphertextVec) const
+const char* cc_EvalMerge_docs = R"doc(
+    Merges multiple ciphertexts with encrypted results in slot 0 into a single ciphertext The slot assignment is done based on the order of ciphertexts in the vector
+
+    Parameters:
+    ----------
+        ciphertextVec (list): vector of ciphertexts to be merged.
+
+    Returns:
+    ----------
+        Ciphertext: resulting ciphertext
+)doc";
+
+//inline virtual Ciphertext<Element> EvalPoly(ConstCiphertext<Element> ciphertext, const std::vector<double> &coefficients) const
+const char* cc_EvalPoly_docs = R"doc(
+    Method for polynomial evaluation for polynomials represented as power series.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        coefficients (list): is the vector of coefficients in the polynomial; the size of the vector is the degree of the polynomial + 1
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation.
+)doc";
+
+//inline Ciphertext<Element> EvalPolyLinear(ConstCiphertext<Element> ciphertext, const std::vector<double> &coefficients)
+const char* cc_EvalPolyLinear_docs = R"doc(
+    Method for polynomial evaluation for polynomials represented in the power series. This uses EvalPolyLinear, which uses a binary tree computation of the polynomial powers.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        coefficients (list): is the vector of coefficients in the polynomial; the size of the vector is the degree of the polynomial
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation.
+)doc";
+
+//inline Ciphertext<Element> EvalPolyPS(ConstCiphertext<Element> ciphertext, const std::vector<double> &coefficients) const
+const char* cc_EvalPolyPS_docs = R"doc(
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): input ciphertext
+        coefficients (list): is the vector of coefficients in the polynomial; the size of the vector is the degree of the polynomial
+
+    Returns:
+    ----------
+        Ciphertext: the result of polynomial evaluation.
+)doc";
+
+//Rescale(cipher)
+const char* cc_Rescale_docs = R"doc(
+    Rescale - An alias for OpenFHE ModReduce method. This is because ModReduce is called Rescale in CKKS.
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): ciphertext
+
+    Returns:
+    ----------
+        Ciphertext: mod reduced ciphertext
+)doc";
+
+//void EvalBootstrapSetup(std::vector<uint32_t> levelBudget = {5, 4}, std::vector<uint32_t> dim1 = {0, 0}, uint32_t slots = 0, uint32_t correctionFactor = 0)
+const char* cc_EvalBootstrapSetup_docs = R"doc(
+    Bootstrap functionality: There are three methods that have to be called in this specific order:
+
+    1. EvalBootstrapSetup: computes and encodes the coefficients for encoding and decoding and stores the necessary parameters
+
+    2. EvalBootstrapKeyGen: computes and stores the keys for rotations and conjugation
+
+    3. EvalBootstrap: refreshes the given ciphertext Sets all parameters for the linear method for the FFT-like method
+
+    Parameters:
+    ----------
+        levelBudget (list):  vector of budgets for the amount of levels in encoding and decoding
+        dim1 (list): vector of inner dimension in the baby-step giant-step routine for encoding and decodingl
+        slots (int): number of slots to be bootstraped
+        correctionFactor (int): alue to rescale message by to improve precision. If set to 0, we use the default logic. This value is only used when get_native_int()=64
+
+    Returns:
+    ----------
+        None
+)doc";
+
+//void EvalBootstrapKeyGen(const PrivateKey<Element> privateKey, uint32_t slots)
+const char* cc_EvalBootstrapKeyGen_docs = R"doc(
+    Generates all automorphism keys for EvalBT. EvalBootstrapKeyGen uses the baby-step/giant-step strategy.
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): private key.
+        slots (int): number of slots to support permutations on.
+
+    Returns:
+    ----------
+        None
+)doc";
+
+//Ciphertext<Element> EvalBootstrap(ConstCiphertext<Element> ciphertext, uint32_t numIterations = 1, uint32_t precision = 0)
+const char* cc_EvalBootstrap_docs = R"doc(
+    Defines the bootstrapping evaluation of ciphertext using either the FFT-like method or the linear method
+
+    Parameters:
+    ----------
+        ciphertext (Ciphertext): the input ciphertext
+        numIterations (int): number of iterations to run iterative bootstrapping (Meta-BTS). Increasing the iterations increases the precision of bootstrapping
+        precision (int): precision of initial bootstrapping algorithm. This value is determined by the user experimentally by first running EvalBootstrap with numIterations = 1 and precision = 0 (unused).
+
+    Returns:
+    ----------
+        Ciphertext: the refreshed ciphertext
+)doc";
+
+//inline std::shared_ptr<std::map<usint, EvalKey<Element>>> EvalAutomorphismKeyGen(const PrivateKey<Element> privateKey, const std::vector<usint> &indexLis
+const char* cc_EvalAutomorphismKeyGen_docs = R"doc(
+    Generate automophism keys for a given private key; Uses the private key for encryption
+
+    Parameters:
+    ----------
+        privateKey (PrivateKey): private key.
+        indexList (list): list of automorphism indices to be computed.
+
+    Returns:
+    ----------
+        dict: returns the evaluation key
+)doc";
+
+//inline std::shared_ptr<std::map<usint, EvalKey<Element>>> EvalAutomorphismKeyGen(const PublicKey<Element> publicKey, const PrivateKey<Element> privateKey, const std::vector<usint> &indexList) const
+const char* cc_EvalAutomorphismKeyGenPublic_docs = R"doc(
+    Generate automophism keys for a given private key.
+
+    Parameters:
+    ----------
+        publicKey (PublicKey): original public key.
+        privateKey (PrivateKey): original private key.
+        indexList (list): list of automorphism indices to be computed.
+
+    Returns:
+    ----------
+        dict: returns the evaluation keys; index 0 of the vector corresponds to plaintext index 2, index 1 to plaintex index 3, etc.
+)doc";
+
+//inline usint FindAutomorphismIndex(const usint idx) const
+const char* cc_FindAutomorphismIndex_docs = R"doc(
+    Find the automorphism index for a given plaintext index
+
+    Parameters:
+    ----------
+        idx (int): plaintext index
+
+    Returns:
+    ----------
+        int: automorphism index
+)doc";
+
+//inline std::vector<usint> FindAutomorphismIndices(const std::vector<usint> idxList) const
+const char* cc_FindAutomorphismIndices_docs = R"doc(
+    Find the automorphism indices for a given list of plaintext indices
+
+    Parameters:
+    ----------
+        idxList (list): list of plaintext indices
+
+    Returns:
+    ----------
+        list: list of automorphism indices
+)doc";
+
+//ClearEvalMultKeys()
+const char* cc_ClearEvalMultKeys_docs = R"doc(
+    ClearEvalMultKeys - flush EvalMultKey cache
+)doc";
+
+//ClearEvalAutomorphismKeys()
+const char* cc_ClearEvalAutomorphismKeys_docs = R"doc(
+    ClearEvalAutomorphismKeys - flush EvalAutomorphismKey cache
+)doc";
+
+//static inline bool SerializeEvalAutomorphismKey(std::ostream &ser, const ST &sertype, std::string id = "")
+const char* cc_SerializeEvalAutomorphismKey_docs = R"doc(
+    SerializeEvalAutomorphismKey for a single EvalAuto key or all of the EvalAuto keys
+
+    Parameters:
+    ----------
+        filename (str): output file
+        sertype (SERJSON, SERBINARY): serialization type
+        id (str): key to serialize; empty string means all keys
+
+    Returns:
+    ----------
+        bool: true on success
+)doc";
+
+//SerializeEvalMultKey(filename,sertype,id)
+const char* cc_SerializeEvalMultKey_docs = R"doc(
+    SerializeEvalMultKey for a single EvalMult key or all of the EvalMult keys
+
+    Parameters:
+    ----------
+        filename (str): output file
+        sertype (SERJSON, SERBINARY): type of serialization
+        id (str): for key to serialize - if empty string, serialize them all
+
+    Returns:
+    ----------
+        bool: true on success
+)doc";
+
+//DeserializeEvalAutomorphismKey(filename,sertype)
+const char* cc_DeserializeEvalAutomorphismKey_docs = R"doc(
+    DeserializeEvalAutomorphismKey deserialize all keys in the serialization deserialized keys silently replace any existing matching keys deserialization will create CryptoContext if necessary
+
+    Parameters:
+    ----------
+        filename (str): path for the file to deserialize from
+        sertype (SERJSON, SERBINARY): type of serialization
+
+    Returns:
+    ----------
+        bool: true on success
+)doc";
+
+//DeserializeEvalMultKey(filename,sertype)
+const char* cc_DeserializeEvalMultKey_docs = R"doc(
+    DeserializeEvalMultKey deserialize all keys in the serialization deserialized keys silently replace any existing matching keys deserialization will create CryptoContext if necessary
+
+    Parameters:
+    ----------
+        filename (str): path for the file to deserialize from
+        sertype (SERJSON, SERBINARY): type of serialization
+
+    Returns:
+    ----------
+        bool: true on success
+)doc";
+
+
+#endif //CRYPTOCONTEXT_DOCSTRINGS_H

+ 38 - 0
include/docstrings/cryptoparameters_docs.h

@@ -0,0 +1,38 @@
+#ifndef CRYPTOPARAMS_DOCSTRINGS_H
+#define CRYPTOPARAMS_DOCSTRINGS_H
+
+const char* ccparams_doc = R"doc(
+    Crypto parameters for the BFV, BGV and CKKS scheme.
+
+    :ivar SCHEME scheme: Scheme ID
+    :ivar PlaintextModulus ptModulus: PlaintextModulus ptModulus is used in BGV/BFV type schemes and impacts noise growth
+    :ivar int digitSize: digitSize is used in BV Key Switching only (KeySwitchTechnique = BV) and impacts noise growth
+    :ivar float standardDeviation: standardDeviation is used for Gaussian error generation
+    :ivar SecretKeyDist secretKeyDist: Secret key distribution: GAUSSIAN, UNIFORM_TERNARY, etc.
+    :ivar int maxRelinSkDeg: Max relinearization degree of secret key polynomial (used for lazy relinearization)
+    :ivar KeySwitchTechnique ksTech: key switching technique: BV or HYBRID currently
+    :ivar ScalingTechnique scalTech: rescaling/modulus switching technique used in CKKS/BGV: FLEXIBLEAUTOEXT, FIXEDMANUL, FLEXIBLEAUTO, etc.
+    :ivar int batchSize: max batch size of messages to be packed in encoding (number of slots)
+    :ivar ProxyReEncryptionMode PREMode: PRE security mode
+    :ivar MultipartyMode multipartyMode: Multiparty security mode in BFV/BGV
+    :ivar ExecutionMode executionMode: Execution mode in CKKS
+    :ivar DecryptionNoiseMode decryptionNoiseMode: Decryption noise mode in CKKS
+    :ivar float noiseEstimate: Noise estimate in CKKS for NOISE_FLOODING_DECRYPT mode.
+    :ivar float desiredPrecision: Desired precision for 128-bit CKKS. We use this value in NOISE_FLOODING_DECRYPT mode to determine the scaling factor.
+    :ivar float statisticalSecurity: Statistical security of CKKS in NOISE_FLOODING_DECRYPT mode. This is the bound on the probability of success that any adversary can have. Specifically, they a probability of success of at most 2^(-statisticalSecurity).
+    :ivar float numAdversarialQueries: This is the number of adversarial queries a user is expecting for their application, which we use to ensure security of CKKS in NOISE_FLOODING_DECRYPT mode.
+    :ivar int thresholdNumOfParties: This is the number of parties in a threshold application, which is used for bound on the joint secret key
+    :ivar int firstModSize: firstModSize and scalingModSize are used to calculate ciphertext modulus. The ciphertext modulus should be seen as: Q = q_0 * q_1 * ... * q_n * q' where q_0 is first prime, and it's number of bits is firstModSize other q_i have same number of bits and is equal to scalingModSize the prime q' is not explicitly given, but it is used internally in CKKS and BGV schemes (in *EXT scaling methods)
+    :ivar int scalingModSize: firstModSize and scalingModSize are used to calculate ciphertext modulus. The ciphertext modulus should be seen as: Q = q_0 * q_1 * ... * q_n * q' where q_0 is first prime, and it's number of bits is firstModSize other q_i have same number of bits and is equal to scalingModSize the prime q' is not explicitly given, but it is used internally in CKKS and BGV schemes (in *EXT scaling methods)
+    :ivar int numLargeDigits: see KeySwitchTechnique - number of digits in HYBRID key switching
+    :ivar int multiplicativeDepth: multiplicative depth
+    :ivar SecurityLevel securityLevel: security level: We use the values from the security standard  at http://homomorphicencryption.org/wp-content/uploads/2018/11/HomomorphicEncryptionStandardv1.1.pdf For given ring dimension and security level we have upper bound of possible highest modulus (Q for BV or P*Q for HYBRID)
+    :ivar int ringDim: ring dimension N of the scheme : the ring is Z_Q[x] / (X^N+1)
+    :ivar int evalAddCount: number of additions (used for setting noise in BGV and BFV)
+    :ivar int keySwitchCount: number of key switching operations (used for setting noise in BGV and BFV)
+    :ivar int multiHopModSize: size of moduli used for PRE in the provable HRA setting
+    :ivar EncryptionTechnique encryptionTechnique: STANDARD or EXTENDED mode for BFV encryption
+    :ivar MultiplicationTechnique multiplicationTechnique: multiplication method in BFV: BEHZ, HPS, etc.
+)doc";
+
+#endif // CRYPTOPARAMS_DOCSTRINGS_H

+ 84 - 0
include/docstrings/plaintext_docs.h

@@ -0,0 +1,84 @@
+#ifndef PLAINTEXT_DOCSTRINGS_H
+#define PLAINTEXT_DOCSTRINGS_H
+
+const char* ptx_GetScalingFactor_docs = R"doc(
+    Get the scaling factor of the plaintext for CKKS-based plaintexts.
+
+    Returns
+    -------
+        float: The scaling factor of the plaintext.
+)doc";
+
+const char* ptx_SetScalingFactor_docs = R"doc(
+    Set the scaling factor of the plaintext for CKKS-based plaintexts.
+
+    Parameters
+    ----------
+        sf (float): The scaling factor to set.
+)doc";
+
+const char* ptx_GetLength_docs = R"doc(
+    Get method to return the length of the plaintext.
+
+    Returns
+    -------
+        int: The length of the plaintext in terms of the number of bits.
+)doc";
+
+const char* ptx_GetSchemeID_docs = R"doc(
+    Get the encryption technique of the plaintext for BFV-based plaintexts.
+
+    Returns
+    -------
+        SCHEME: The scheme ID of the plaintext.
+)doc";
+
+const char* ptx_SetLength_docs = R"doc(
+    resize the plaintext; only works for plaintexts that support a resizable vector (coefpacked)
+
+    Parameters
+    ----------
+        newSize (int): -
+)doc";
+
+const char* ptx_IsEncoded_docs = R"doc(
+    Check if the plaintext is encoded.
+
+    Returns
+    -------
+        bool: True if the plaintext is encoded, False otherwise.
+)doc";
+
+const char* ptx_GetLogPrecision_docs = R"doc(
+    Get the log of the plaintext precision.
+
+    Returns
+    -------
+        float: The log of the plaintext precision.
+)doc";
+
+const char* ptx_Encode_docs = R"doc(
+    Encode the plaintext into a polynomial
+
+    Returns
+    -------
+        None
+)doc";
+
+const char* ptx_Decode_docs = R"doc(
+    Decode the polynomial into a plaintext
+
+    Returns
+    -------
+        None
+)doc";
+
+const char* ptx_GetCKKSPackedValue_docs = R"doc(
+    Get the packed value of the plaintext for CKKS-based plaintexts.
+
+    Returns
+    -------
+        List[complex]: The packed value of the plaintext.
+)doc";
+
+#endif // PLAINTEXT_DOCSTRINGS_H

+ 386 - 112
src/bindings.cpp

@@ -12,6 +12,9 @@
 #include "bindings.h"
 #include "cryptocontext_wrapper.h"
 #include "binfhe_bindings.h"
+#include "cryptocontext_docs.h"
+#include "plaintext_docs.h"
+#include "ciphertext_docs.h"
 
 using namespace lbcrypto;
 namespace py = pybind11;
@@ -37,7 +40,7 @@ void bind_parameters(py::module &m,const std::string name)
         .def("GetDesiredPrecision", &CCParams<T>::GetDesiredPrecision)
         .def("GetStatisticalSecurity", &CCParams<T>::GetStatisticalSecurity)
         .def("GetNumAdversarialQueries", &CCParams<T>::GetNumAdversarialQueries)
-        .def("GetThresholdNumOfParties", &CCParams<T>::GetThresholdNumOfParties)
+        //.def("GetThresholdNumOfParties", &CCParams<T>::GetThresholdNumOfParties)
         .def("GetKeySwitchTechnique", &CCParams<T>::GetKeySwitchTechnique)
         .def("GetScalingTechnique", &CCParams<T>::GetScalingTechnique)
         .def("GetBatchSize", &CCParams<T>::GetBatchSize)
@@ -66,7 +69,7 @@ void bind_parameters(py::module &m,const std::string name)
         .def("SetDesiredPrecision", &CCParams<T>::SetDesiredPrecision)
         .def("SetStatisticalSecurity", &CCParams<T>::SetStatisticalSecurity)
         .def("SetNumAdversarialQueries", &CCParams<T>::SetNumAdversarialQueries)
-        .def("SetThresholdNumOfParties", &CCParams<T>::SetThresholdNumOfParties)
+        //.def("SetThresholdNumOfParties", &CCParams<T>::SetThresholdNumOfParties)
         .def("SetKeySwitchTechnique", &CCParams<T>::SetKeySwitchTechnique)
         .def("SetScalingTechnique", &CCParams<T>::SetScalingTechnique)
         .def("SetBatchSize", &CCParams<T>::SetBatchSize)
@@ -95,166 +98,413 @@ void bind_crypto_context(py::module &m)
 {
     py::class_<CryptoContextImpl<DCRTPoly>, std::shared_ptr<CryptoContextImpl<DCRTPoly>>>(m, "CryptoContext")
         .def(py::init<>())
-        .def("GetKeyGenLevel", &CryptoContextImpl<DCRTPoly>::GetKeyGenLevel)
-        .def("SetKeyGenLevel", &CryptoContextImpl<DCRTPoly>::SetKeyGenLevel)
+        .def("GetKeyGenLevel", &CryptoContextImpl<DCRTPoly>::GetKeyGenLevel, cc_GetKeyGenLevel_docs)
+        .def("SetKeyGenLevel", &CryptoContextImpl<DCRTPoly>::SetKeyGenLevel, cc_SetKeyGenLevel_docs,
+             py::arg("level"))
         //.def("GetScheme",&CryptoContextImpl<DCRTPoly>::GetScheme)
         //.def("GetCryptoParameters", &CryptoContextImpl<DCRTPoly>::GetCryptoParameters)
-        .def("GetRingDimension", &CryptoContextImpl<DCRTPoly>::GetRingDimension)
-        .def("Enable", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(PKESchemeFeature)>(&CryptoContextImpl<DCRTPoly>::Enable), "Enable a feature for the CryptoContext")
-        .def("KeyGen", &CryptoContextImpl<DCRTPoly>::KeyGen, "Generate a key pair with public and private keys")
-        .def("EvalMultKeyGen", &CryptoContextImpl<DCRTPoly>::EvalMultKeyGen, "Generate the evaluation key for multiplication")
-        .def("EvalMultKeysGen", &CryptoContextImpl<DCRTPoly>::EvalMultKeysGen)
-        .def("EvalRotateKeyGen", &CryptoContextImpl<DCRTPoly>::EvalRotateKeyGen, "Generate the evaluation key for rotation",
-             py::arg("privateKey"), py::arg("indexList"), py::arg("publicKey") = nullptr)
-        .def("MakeStringPlaintext", &CryptoContextImpl<DCRTPoly>::MakeStringPlaintext)
-        .def("MakePackedPlaintext", &CryptoContextImpl<DCRTPoly>::MakePackedPlaintext, "Make a plaintext from a vector of integers",
-             py::arg("value"), py::arg("depth") = 1, py::arg("level") = 0)
-        .def("MakeCoefPackedPlaintext", &CryptoContextImpl<DCRTPoly>::MakeCoefPackedPlaintext)
+        .def("GetRingDimension", &CryptoContextImpl<DCRTPoly>::GetRingDimension, cc_GetRingDimension_docs)
+        .def("Enable", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(PKESchemeFeature)>(&CryptoContextImpl<DCRTPoly>::Enable), cc_Enable_docs,
+             py::arg("feature"))
+        .def("KeyGen", &CryptoContextImpl<DCRTPoly>::KeyGen, cc_KeyGen_docs)
+        .def("EvalMultKeyGen", &CryptoContextImpl<DCRTPoly>::EvalMultKeyGen,
+             cc_EvalMultKeyGen_docs,
+             py::arg("privateKey"))
+        .def("EvalMultKeysGen", &CryptoContextImpl<DCRTPoly>::EvalMultKeysGen,
+             cc_EvalMultKeysGen_docs,
+             py::arg("privateKey"))
+        .def("EvalRotateKeyGen", &CryptoContextImpl<DCRTPoly>::EvalRotateKeyGen,
+             cc_EvalRotateKeyGen_docs,
+             py::arg("privateKey"),
+             py::arg("indexList"),
+             py::arg("publicKey") = nullptr)
+        .def("MakeStringPlaintext", &CryptoContextImpl<DCRTPoly>::MakeStringPlaintext,
+             cc_MakeStringPlaintext_docs,
+             py::arg("str"))
+        .def("MakePackedPlaintext", &CryptoContextImpl<DCRTPoly>::MakePackedPlaintext,
+             cc_MakePackedPlaintext_docs,
+             py::arg("value"),
+             py::arg("depth") = 1,
+             py::arg("level") = 0)
+        .def("MakeCoefPackedPlaintext", &CryptoContextImpl<DCRTPoly>::MakeCoefPackedPlaintext,
+            cc_MakeCoefPackedPlaintext_docs,
+            py::arg("value"),
+            py::arg("depth") = 1,
+            py::arg("level") = 0)
         // TODO (Oliveira): allow user to specify different params values
-        .def("MakeCKKSPackedPlaintext", static_cast<Plaintext (CryptoContextImpl<DCRTPoly>::*)(const std::vector<std::complex<double>> &, size_t, uint32_t, const std::shared_ptr<ParmType>, usint) const>(&CryptoContextImpl<DCRTPoly>::MakeCKKSPackedPlaintext), "Make a CKKS plaintext from a vector of complex doubles",
+        .def("MakeCKKSPackedPlaintext", static_cast<Plaintext (CryptoContextImpl<DCRTPoly>::*)(const std::vector<std::complex<double>> &, size_t, uint32_t, const std::shared_ptr<ParmType>, usint) const>(&CryptoContextImpl<DCRTPoly>::MakeCKKSPackedPlaintext), cc_MakeCKKSPackedPlaintextComplex_docs,
              py::arg("value"),
              py::arg("depth") = static_cast<size_t>(1),
              py::arg("level") = static_cast<uint32_t>(0),
              py::arg("params") = py::none(),
              py::arg("slots") = 0)
-        .def("MakeCKKSPackedPlaintext", static_cast<Plaintext (CryptoContextImpl<DCRTPoly>::*)(const std::vector<double> &, size_t, uint32_t, const std::shared_ptr<ParmType>, usint) const>(&CryptoContextImpl<DCRTPoly>::MakeCKKSPackedPlaintext), "Make a CKKS plaintext from a vector of doubles",
+        .def("MakeCKKSPackedPlaintext", static_cast<Plaintext (CryptoContextImpl<DCRTPoly>::*)(const std::vector<double> &, size_t, uint32_t, const std::shared_ptr<ParmType>, usint) const>(&CryptoContextImpl<DCRTPoly>::MakeCKKSPackedPlaintext), cc_MakeCKKSPlaintextReal_docs,
              py::arg("value"),
              py::arg("depth") = static_cast<size_t>(1),
              py::arg("level") = static_cast<uint32_t>(0),
              py::arg("params") = py::none(),
              py::arg("slots") = 0)
-        .def("EvalRotate", &CryptoContextImpl<DCRTPoly>::EvalRotate, "Rotate a ciphertext")
-        .def("EvalFastRotationPrecompute", &EvalFastRotationPrecomputeWrapper)
-        .def("EvalFastRotation", &EvalFastRotationWrapper)
-        .def("EvalFastRotationExt", &EvalFastRotationExtWrapper)
-        .def("EvalAtIndexKeyGen", &CryptoContextImpl<DCRTPoly>::EvalAtIndexKeyGen)
-        .def("EvalAtIndex", &CryptoContextImpl<DCRTPoly>::EvalAtIndex)
-        .def("Encrypt", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(const PublicKey<DCRTPoly>, Plaintext) const>(&CryptoContextImpl<DCRTPoly>::Encrypt),
-             "Encrypt a plaintext using public key")
-        .def("Decrypt", static_cast<Plaintext (*)(CryptoContext<DCRTPoly> &, const PrivateKey<DCRTPoly>, ConstCiphertext<DCRTPoly>)>(&DecryptWrapper),
-             "Decrypt a ciphertext using private key")
-        .def("Decrypt", static_cast<Plaintext (*)(CryptoContext<DCRTPoly> &, ConstCiphertext<DCRTPoly>, const PrivateKey<DCRTPoly>)>(&DecryptWrapper),
-             "Decrypt a ciphertext using private key")
-        .def("EvalAdd", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalAdd), "Add two ciphertexts")
-        .def("EvalAdd", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, double) const>(&CryptoContextImpl<DCRTPoly>::EvalAdd), "Add a ciphertext with a scalar")
-        .def("EvalAddInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalAddInPlace))
-        .def("EvalAddInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, ConstPlaintext) const>(&CryptoContextImpl<DCRTPoly>::EvalAddInPlace))
-        .def("EvalAddInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(ConstPlaintext, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalAddInPlace))
-        .def("EvalAddMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalAddMutable))
-        .def("EvalAddMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Plaintext) const>(&CryptoContextImpl<DCRTPoly>::EvalAddMutable))
-        .def("EvalAddMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Plaintext, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalAddMutable))
-        .def("EvalAddMutableInPlace", &CryptoContextImpl<DCRTPoly>::EvalAddMutableInPlace)
-        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalSub), "Subtract two ciphertexts")
-        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, double) const>(&CryptoContextImpl<DCRTPoly>::EvalSub), "Subtract double from ciphertext")
-        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(double, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalSub), "Subtract ciphertext from double")
-        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstPlaintext) const>(&CryptoContextImpl<DCRTPoly>::EvalSub), "Subtract plaintext from ciphertext")
-        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstPlaintext, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalSub), "Subtract ciphertext from plaintext")
-        .def("EvalSubInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalSubInPlace))
-        .def("EvalSubInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, double) const>(&CryptoContextImpl<DCRTPoly>::EvalSubInPlace))
-        .def("EvalSubInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(double, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalSubInPlace))
-        .def("EvalSubMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalSubMutable))
-        .def("EvalSubMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Plaintext) const>(&CryptoContextImpl<DCRTPoly>::EvalSubMutable))
-        .def("EvalSubMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Plaintext, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalSubMutable))
-        .def("EvalSubMutableInPlace", &CryptoContextImpl<DCRTPoly>::EvalSubMutableInPlace)
-        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalMult), "Multiply two ciphertexts")
-        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, double) const>(&CryptoContextImpl<DCRTPoly>::EvalMult), "Multiply a ciphertext with a scalar")
-        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstPlaintext) const>(&CryptoContextImpl<DCRTPoly>::EvalMult))
-        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstPlaintext, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalMult))
-        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(double, ConstCiphertext<DCRTPoly>) const>(&CryptoContextImpl<DCRTPoly>::EvalMult))
-        .def("EvalMultMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalMultMutable))
-        .def("EvalMultMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Plaintext) const>(&CryptoContextImpl<DCRTPoly>::EvalMultMutable))
-        .def("EvalMultMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Plaintext, Ciphertext<DCRTPoly> &) const>(&CryptoContextImpl<DCRTPoly>::EvalMultMutable))
-        .def("EvalMultMutableInPlace", &CryptoContextImpl<DCRTPoly>::EvalMultMutableInPlace)
-        .def("EvalSquare", &CryptoContextImpl<DCRTPoly>::EvalSquare)
-        .def("EvalSquareMutable", &CryptoContextImpl<DCRTPoly>::EvalSquareMutable)
-        .def("EvalSquareInPlace", &CryptoContextImpl<DCRTPoly>::EvalSquareInPlace)
-        .def("EvalMultNoRelin", &CryptoContextImpl<DCRTPoly>::EvalMultNoRelin)
-        .def("Relinearize", &CryptoContextImpl<DCRTPoly>::Relinearize)
-        .def("RelinearizeInPlace", &CryptoContextImpl<DCRTPoly>::RelinearizeInPlace)
-        .def("EvalMultAndRelinearize", &CryptoContextImpl<DCRTPoly>::EvalMultAndRelinearize)
-        .def("EvalNegate", &CryptoContextImpl<DCRTPoly>::EvalNegate)
-        .def("EvalNegateInPlace", &CryptoContextImpl<DCRTPoly>::EvalNegateInPlace)
+        .def("EvalRotate", &CryptoContextImpl<DCRTPoly>::EvalRotate,
+            cc_EvalRotate_docs,
+            py::arg("ciphertext"),
+            py::arg("index"))
+        .def("EvalFastRotationPrecompute", &EvalFastRotationPrecomputeWrapper,
+            cc_EvalFastRotationPreCompute_docs,
+            py::arg("ciphertext"))
+        .def("EvalFastRotation", &EvalFastRotationWrapper,
+            cc_EvalFastRotation_docs,
+            py::arg("ciphertext"),
+            py::arg("index"),
+            py::arg("m"),
+            py::arg("digits"))
+        .def("EvalFastRotationExt", &EvalFastRotationExtWrapper, 
+            cc_EvalFastRotationExt_docs,
+            py::arg("ciphertext"),
+            py::arg("index"),
+            py::arg("digits"),
+            py::arg("addFirst"))
+        .def("EvalAtIndexKeyGen", &CryptoContextImpl<DCRTPoly>::EvalAtIndexKeyGen,
+            cc_EvalAtIndexKeyGen_docs,
+            py::arg("privateKey"),
+            py::arg("indexList"),
+            py::arg("publicKey") = nullptr)
+        .def("EvalAtIndex", &CryptoContextImpl<DCRTPoly>::EvalAtIndex,
+            cc_EvalAtIndex_docs,
+            py::arg("ciphertext"),
+            py::arg("index"))
+        .def("Encrypt", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(const PublicKey<DCRTPoly>, Plaintext) const>
+            (&CryptoContextImpl<DCRTPoly>::Encrypt),
+            cc_Encrypt_docs,
+            py::arg("publicKey"),
+            py::arg("plaintext"))
+        .def("Decrypt", static_cast<Plaintext (*)(CryptoContext<DCRTPoly> &, const PrivateKey<DCRTPoly>, ConstCiphertext<DCRTPoly>)>
+            (&DecryptWrapper), cc_Decrypt_docs,
+            py::arg("privateKey"),
+            py::arg("ciphertext"))
+        .def("Decrypt", static_cast<Plaintext (*)(CryptoContext<DCRTPoly> &, ConstCiphertext<DCRTPoly>, const PrivateKey<DCRTPoly>)>
+            (&DecryptWrapper), cc_Decrypt_docs,
+            py::arg("ciphertext"),
+            py::arg("privateKey"))
+        .def("EvalAdd", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAdd), 
+            cc_EvalAdd_docs,
+            py::arg("ciphertext1"),
+            py::arg("ciphertext2"))
+        .def("EvalAdd", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, double) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAdd), 
+            cc_EvalAddfloat_docs,
+            py::arg("ciphertext"),
+            py::arg("scalar"))
+        .def("EvalAddInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAddInPlace),
+            cc_EvalAddInPlace_docs,
+            py::arg("ciphertext1"),
+            py::arg("ciphertext2"))
+        .def("EvalAddInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, ConstPlaintext) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAddInPlace),
+            cc_EvalAddInPlacePlaintext_docs,
+            py::arg("ciphertext"),
+            py::arg("plaintext"))
+        .def("EvalAddInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(ConstPlaintext, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAddInPlace),
+            "",
+            py::arg("plaintext"),
+            py::arg("ciphertext"))
+        .def("EvalAddMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAddMutable),
+            cc_EvalAddMutable_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalAddMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Plaintext) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAddMutable),
+            cc_EvalAddMutablePlaintext_docs,
+            py::arg("ciphertext"),
+            py::arg("plaintext"))
+        .def("EvalAddMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Plaintext, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalAddMutable),
+            "",
+            py::arg("plaintext"),
+            py::arg("ciphertext"))
+        .def("EvalAddMutableInPlace", &CryptoContextImpl<DCRTPoly>::EvalAddMutableInPlace,
+            cc_EvalAddMutableInPlace_docs,
+            py::arg("ciphertext1"),
+            py::arg("ciphertext2"))
+        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSub),
+            cc_EvalSub_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, double) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSub),
+            cc_EvalSubfloat_docs,
+            py::arg("ciphertext"),
+            py::arg("constant"))
+        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(double, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSub),
+            "",
+            py::arg("constant"),
+            py::arg("ciphertext"))
+        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstPlaintext) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSub),
+            cc_EvalSubPlaintext_docs,
+            py::arg("ciphertext"),
+            py::arg("plaintext"))
+        .def("EvalSub", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstPlaintext, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSub),
+            "",
+            py::arg("plaintext"),
+            py::arg("ciphertext"))
+        .def("EvalSubInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSubInPlace),
+            cc_EvalSubInPlace_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalSubInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, double) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSubInPlace),
+            cc_EvalSubInPlacefloat_docs,
+            py::arg("ciphertext"),
+            py::arg("constant"))
+        .def("EvalSubInPlace", static_cast<void (CryptoContextImpl<DCRTPoly>::*)(double, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSubInPlace),
+            "",
+            py::arg("constant"),
+            py::arg("ciphertext"))
+        .def("EvalSubMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSubMutable),
+            cc_EvalSubMutable_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalSubMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Plaintext) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSubMutable),
+            cc_EvalSubMutablePlaintext_docs,
+            py::arg("ciphertext"),
+            py::arg("plaintext"))
+        .def("EvalSubMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Plaintext, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalSubMutable),
+            "",
+            py::arg("plaintext"),
+            py::arg("ciphertext"))
+        .def("EvalSubMutableInPlace", &CryptoContextImpl<DCRTPoly>::EvalSubMutableInPlace,
+            cc_EvalSubMutableInPlace_docs,
+            py::arg("ciphertext1"),
+            py::arg("ciphertext2"))
+        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMult),
+            cc_EvalMult_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, double) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMult),
+            cc_EvalMultfloat_docs,
+            py::arg("ciphertext"),
+            py::arg("constant"))
+        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstPlaintext) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMult),
+            cc_EvalMultPlaintext_docs,
+            py::arg("ciphertext"),
+            py::arg("plaintext"))
+        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstPlaintext, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMult),
+            "",
+            py::arg("plaintext"),
+            py::arg("ciphertext"))
+        .def("EvalMult", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(double, ConstCiphertext<DCRTPoly>) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMult),
+            "",
+            py::arg("constant"),
+            py::arg("ciphertext"))
+        .def("EvalMultMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMultMutable),
+            cc_EvalMultMutable_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalMultMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Ciphertext<DCRTPoly> &, Plaintext) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMultMutable),
+            cc_EvalMultMutablePlaintext_docs,
+            py::arg("ciphertext"),
+            py::arg("plaintext"))
+        .def("EvalMultMutable", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(Plaintext, Ciphertext<DCRTPoly> &) const>
+            (&CryptoContextImpl<DCRTPoly>::EvalMultMutable),
+            "",
+            py::arg("plaintext"),
+            py::arg("ciphertext"))
+        .def("EvalMultMutableInPlace", &CryptoContextImpl<DCRTPoly>::EvalMultMutableInPlace,
+            cc_EvalMultMutableInPlace_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalSquare", &CryptoContextImpl<DCRTPoly>::EvalSquare,
+            cc_EvalSquare_docs,
+            py::arg("ct"))
+        .def("EvalSquareMutable", &CryptoContextImpl<DCRTPoly>::EvalSquareMutable,
+            cc_EvalSquareMutable_docs,
+            py::arg("ct"))
+        .def("EvalSquareInPlace", &CryptoContextImpl<DCRTPoly>::EvalSquareInPlace,
+            cc_EvalSquareInPlace_docs,
+            py::arg("ct"))
+        .def("EvalMultNoRelin", &CryptoContextImpl<DCRTPoly>::EvalMultNoRelin,
+            cc_EvalMultNoRelin_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("Relinearize", &CryptoContextImpl<DCRTPoly>::Relinearize,
+            cc_Relinearize_docs,
+            py::arg("ciphertext"))
+        .def("RelinearizeInPlace", &CryptoContextImpl<DCRTPoly>::RelinearizeInPlace,
+            cc_RelinearizeInPlace_docs,
+            py::arg("ciphertext"))
+        .def("EvalMultAndRelinearize", &CryptoContextImpl<DCRTPoly>::EvalMultAndRelinearize,
+            cc_EvalMultAndRelinearize_docs,
+            py::arg("ct1"),
+            py::arg("ct2"))
+        .def("EvalNegate", &CryptoContextImpl<DCRTPoly>::EvalNegate,
+            cc_EvalNegate_docs,
+            py::arg("ct"))
+        .def("EvalNegateInPlace", &CryptoContextImpl<DCRTPoly>::EvalNegateInPlace,
+            cc_EvalNegateInPlace_docs,
+            py::arg("ct"))
         .def("EvalLogistic", &CryptoContextImpl<DCRTPoly>::EvalLogistic,
-             py::arg("ciphertext"),
-             py::arg("a"),
-             py::arg("b"),
-             py::arg("degree"))
-        .def("EvalChebyshevSeries", &CryptoContextImpl<DCRTPoly>::EvalChebyshevSeries)
-        .def("EvalChebyshevSeriesLinear", &CryptoContextImpl<DCRTPoly>::EvalChebyshevSeriesLinear)
-        .def("EvalChebyshevSeriesPS", &CryptoContextImpl<DCRTPoly>::EvalChebyshevSeriesPS)
+            cc_EvalLogistic_docs,
+            py::arg("ciphertext"),
+            py::arg("a"),
+            py::arg("b"),
+            py::arg("degree"))
+        .def("EvalChebyshevSeries", &CryptoContextImpl<DCRTPoly>::EvalChebyshevSeries,
+            cc_EvalChebyshevSeries_docs,
+            py::arg("ciphertext"),
+            py::arg("coefficients"),
+            py::arg("a"),
+            py::arg("b"))
+        .def("EvalChebyshevSeriesLinear", &CryptoContextImpl<DCRTPoly>::EvalChebyshevSeriesLinear,
+            cc_EvalChebyshevSeriesLinear_docs,
+            py::arg("ciphertext"),
+            py::arg("coefficients"),
+            py::arg("a"),
+            py::arg("b"))
+        .def("EvalChebyshevSeriesPS", &CryptoContextImpl<DCRTPoly>::EvalChebyshevSeriesPS,
+            cc_EvalChebyshevSeriesPS_docs,
+            py::arg("ciphertext"),
+            py::arg("coefficients"),
+            py::arg("a"),
+            py::arg("b"))
         .def("EvalChebyshevFunction", &CryptoContextImpl<DCRTPoly>::EvalChebyshevFunction,
+            cc_EvalChebyshevFunction_docs,
              py::arg("func"),
              py::arg("ciphertext"),
              py::arg("a"),
              py::arg("b"),
              py::arg("degree"))
         .def("EvalSin", &CryptoContextImpl<DCRTPoly>::EvalSin,
+             cc_EvalSin_docs,
              py::arg("ciphertext"),
              py::arg("a"),
              py::arg("b"),
              py::arg("degree"))
         .def("EvalCos", &CryptoContextImpl<DCRTPoly>::EvalCos,
+             cc_EvalCos_docs,
              py::arg("ciphertext"),
              py::arg("a"),
              py::arg("b"),
              py::arg("degree"))
         .def("EvalDivide", &CryptoContextImpl<DCRTPoly>::EvalDivide,
+             cc_EvalDivide_docs,
              py::arg("ciphertext"),
              py::arg("a"),
              py::arg("b"),
              py::arg("degree"))
         .def("EvalSumKeyGen", &CryptoContextImpl<DCRTPoly>::EvalSumKeyGen,
+             cc_EvalSumKeyGen_docs,
              py::arg("privateKey"),
              py::arg("publicKey") = py::none())
+        //TODO (Oliveira, R.): Solve pointer handling bug when dealing with EvalKeyMap object for the next functions 
         .def("EvalSumRowsKeyGen", &CryptoContextImpl<DCRTPoly>::EvalSumRowsKeyGen,
+             cc_EvalSumRowsKeyGen_docs,
              py::arg("privateKey"),
              py::arg("publicKey") = py::none(),
              py::arg("rowSize") = 0,
              py::arg("subringDim") = 0)
         .def("EvalSumColsKeyGen", &CryptoContextImpl<DCRTPoly>::EvalSumColsKeyGen,
+             cc_EvalSumColsKeyGen_docs,
              py::arg("privateKey"),
              py::arg("publicKey") = py::none())
         .def("EvalSumRows", &CryptoContextImpl<DCRTPoly>::EvalSumRows,
+             cc_EvalSumRows_docs,
              py::arg("ciphertext"),
              py::arg("rowSize"),
              py::arg("evalSumKeyMap"),
              py::arg("subringDim") = 0)
         .def("EvalSumCols", &CryptoContextImpl<DCRTPoly>::EvalSumCols,
+             cc_EvalSumCols_docs,
              py::arg("ciphertext"),
              py::arg("rowSize"),
              py::arg("evalSumKeyMap"))
-        .def("EvalInnerProduct", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)
-            (ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>, usint) const>(&CryptoContextImpl<DCRTPoly>::EvalInnerProduct))
-        .def("EvalInnerProduct", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)
-            (ConstCiphertext<DCRTPoly>, ConstPlaintext, usint) const>(&CryptoContextImpl<DCRTPoly>::EvalInnerProduct))        
-        .def("EvalPoly", &CryptoContextImpl<DCRTPoly>::EvalPoly)
-        .def("EvalPolyLinear", &CryptoContextImpl<DCRTPoly>::EvalPolyLinear)
-        .def("EvalPolyPS", &CryptoContextImpl<DCRTPoly>::EvalPolyPS)
-        .def("Rescale", &CryptoContextImpl<DCRTPoly>::Rescale, "Rescale a ciphertext")
+        .def("EvalInnerProduct", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstCiphertext<DCRTPoly>, usint) const>(&CryptoContextImpl<DCRTPoly>::EvalInnerProduct),
+             cc_EvalInnerProduct_docs,
+             py::arg("ciphertext1"),
+             py::arg("ciphertext2"),
+             py::arg("batchSize"))
+        .def("EvalInnerProduct", static_cast<Ciphertext<DCRTPoly> (CryptoContextImpl<DCRTPoly>::*)(ConstCiphertext<DCRTPoly>, ConstPlaintext, usint) const>(&CryptoContextImpl<DCRTPoly>::EvalInnerProduct),
+             cc_EvalInnerProductPlaintext_docs,
+             py::arg("ciphertext"),
+             py::arg("plaintext"),
+             py::arg("batchSize"))
+        .def("EvalMerge", &CryptoContextImpl<DCRTPoly>::EvalMerge,
+             cc_EvalMerge_docs,
+             py::arg("ciphertextVec"))
+        .def("EvalPoly", &CryptoContextImpl<DCRTPoly>::EvalPoly,
+             cc_EvalPoly_docs,
+             py::arg("ciphertext"),
+             py::arg("coefficients"))
+        .def("EvalPolyLinear", &CryptoContextImpl<DCRTPoly>::EvalPolyLinear,
+             cc_EvalPolyLinear_docs,
+             py::arg("ciphertext"),
+             py::arg("coefficients"))
+        .def("EvalPolyPS", &CryptoContextImpl<DCRTPoly>::EvalPolyPS,
+             cc_EvalPolyPS_docs,
+             py::arg("ciphertext"),
+             py::arg("coefficients"))
+        .def("Rescale", &CryptoContextImpl<DCRTPoly>::Rescale,
+             cc_Rescale_docs,
+             py::arg("ciphertext"))
         .def("EvalBootstrapSetup", &CryptoContextImpl<DCRTPoly>::EvalBootstrapSetup,
+             cc_EvalBootstrapSetup_docs,
              py::arg("levelBudget") = std::vector<uint32_t>({5, 4}),
              py::arg("dim1") = std::vector<uint32_t>({0, 0}),
              py::arg("slots") = 0,
              py::arg("correctionFactor") = 0)
         .def("EvalBootstrapKeyGen", &CryptoContextImpl<DCRTPoly>::EvalBootstrapKeyGen,
+             cc_EvalBootstrapKeyGen_docs,
              py::arg("privateKey"),
              py::arg("slots"))
         .def("EvalBootstrap", &CryptoContextImpl<DCRTPoly>::EvalBootstrap,
+             cc_EvalBootstrap_docs,
              py::arg("ciphertext"),
              py::arg("numIterations") = 1,
              py::arg("precision") = 0)
-        .def("EvalAutomorphismKeyGen", &EvalAutomorphismKeyGenWrapper, py::return_value_policy::reference_internal)
-        .def("EvalAutomorphismKeyGen", &EvalAutomorphismKeyGenWrapper_PublicKey, py::return_value_policy::reference_internal)
-        .def("FindAutomorphismIndex", &CryptoContextImpl<DCRTPoly>::FindAutomorphismIndex)
-        .def("FindAutomorphismIndices", &CryptoContextImpl<DCRTPoly>::FindAutomorphismIndices)
+        //TODO (Oliveira, R.): Solve pointer handling bug when returning EvalKeyMap objects for the next functions
+        .def("EvalAutomorphismKeyGen", &EvalAutomorphismKeyGenWrapper, 
+            cc_EvalAutomorphismKeyGen_docs,
+            py::arg("privateKey"),
+            py::arg("indexList"),
+            py::return_value_policy::reference_internal)
+        .def("EvalAutomorphismKeyGen", &EvalAutomorphismKeyGenWrapper_PublicKey, 
+            cc_EvalAutomorphismKeyGenPublic_docs,
+            py::arg("publicKey"),
+            py::arg("privateKey"),
+            py::arg("indexList"),
+            py::return_value_policy::reference_internal)
+        .def("FindAutomorphismIndex", &CryptoContextImpl<DCRTPoly>::FindAutomorphismIndex,
+            cc_FindAutomorphismIndex_docs,
+            py::arg("idx"))
+        .def("FindAutomorphismIndices", &CryptoContextImpl<DCRTPoly>::FindAutomorphismIndices,
+            cc_FindAutomorphismIndices_docs,
+            py::arg("idxList"))
         .def_static(
             "ClearEvalMultKeys", []()
             { CryptoContextImpl<DCRTPoly>::ClearEvalMultKeys(); },
-            "Clear the evaluation keys for multiplication")
+            cc_ClearEvalMultKeys_docs)
         .def_static(
             "ClearEvalAutomorphismKeys", []()
             { CryptoContextImpl<DCRTPoly>::ClearEvalAutomorphismKeys(); },
-            "Clear the evaluation keys for rotation")
+            cc_ClearEvalAutomorphismKeys_docs)
         .def_static(
             "SerializeEvalMultKey", [](const std::string &filename, const SerType::SERBINARY &sertype, std::string id = "")
             {
@@ -263,8 +513,8 @@ void bind_crypto_context(py::module &m)
                 res = CryptoContextImpl<DCRTPoly>::SerializeEvalMultKey<SerType::SERBINARY>(outfile, sertype, id);
                 outfile.close();
                 return res; },
-            py::arg("filename"), py::arg("sertype"), py::arg("id") = "",
-            "Serialize an evaluation key for multiplication")
+            cc_SerializeEvalMultKey_docs,
+            py::arg("filename"), py::arg("sertype"), py::arg("id") = "")
         .def_static(
             "SerializeEvalAutomorphismKey", [](const std::string &filename, const SerType::SERBINARY &sertype, std::string id = "")
             {
@@ -273,7 +523,8 @@ void bind_crypto_context(py::module &m)
                 res = CryptoContextImpl<DCRTPoly>::SerializeEvalAutomorphismKey<SerType::SERBINARY>(outfile, sertype, id);
                 outfile.close();
                 return res; },
-            py::arg("filename"), py::arg("sertype"), py::arg("id") = "", "Serialize evaluation keys for rotation")
+            cc_SerializeEvalAutomorphismKey_docs,
+            py::arg("filename"), py::arg("sertype"), py::arg("id") = "")
         .def_static("DeserializeEvalMultKey", [](std::shared_ptr<CryptoContextImpl<DCRTPoly>> &self, const std::string &filename, const SerType::SERBINARY &sertype)
                     {
                         std::ifstream emkeys(filename, std::ios::in | std::ios::binary);
@@ -282,7 +533,10 @@ void bind_crypto_context(py::module &m)
                          }
                         bool res;
                         res = self->DeserializeEvalMultKey<SerType::SERBINARY>(emkeys, sertype);
-                        return res; })
+                        return res; },
+                        cc_DeserializeEvalMultKey_docs,
+                        py::arg("self"),
+                        py::arg("filename"), py::arg("sertype"))
         .def_static("DeserializeEvalAutomorphismKey", [](std::shared_ptr<CryptoContextImpl<DCRTPoly>> &self, const std::string &filename, const SerType::SERBINARY &sertype)
                     {
                         std::ifstream erkeys(filename, std::ios::in | std::ios::binary);
@@ -291,12 +545,18 @@ void bind_crypto_context(py::module &m)
                          }
                         bool res;
                         res = self->DeserializeEvalAutomorphismKey<SerType::SERBINARY>(erkeys, sertype);
-                        return res; });
+                        return res; },
+                        cc_DeserializeEvalAutomorphismKey_docs,
+                        py::arg("self"),
+                        py::arg("filename"), py::arg("sertype"));
 
     // Generator Functions
-    m.def("GenCryptoContext", &GenCryptoContext<CryptoContextBFVRNS>);
-    m.def("GenCryptoContext", &GenCryptoContext<CryptoContextBGVRNS>);
-    m.def("GenCryptoContext", &GenCryptoContext<CryptoContextCKKSRNS>);
+    m.def("GenCryptoContext", &GenCryptoContext<CryptoContextBFVRNS>,
+        py::arg("params"));
+    m.def("GenCryptoContext", &GenCryptoContext<CryptoContextBGVRNS>,
+        py::arg("params"));
+    m.def("GenCryptoContext", &GenCryptoContext<CryptoContextCKKSRNS>,
+        py::arg("params"));
     m.def("ReleaseAllContexts", &CryptoContextFactory<DCRTPoly>::ReleaseAllContexts);
 }
 
@@ -471,17 +731,28 @@ void bind_keys(py::module &m)
 void bind_encodings(py::module &m)
 {
     py::class_<PlaintextImpl, std::shared_ptr<PlaintextImpl>>(m, "Plaintext")
-        .def("GetScalingFactor", &PlaintextImpl::GetScalingFactor)
-        .def("SetScalingFactor", &PlaintextImpl::SetScalingFactor)
-        .def("GetLength", &PlaintextImpl::GetLength)
-        .def("GetSchemeID", &PlaintextImpl::GetSchemeID)
-        .def("SetLength", &PlaintextImpl::SetLength)
-        .def("IsEncoded", &PlaintextImpl::IsEncoded)
-        .def("GetLogPrecision", &PlaintextImpl::GetLogPrecision)
-        //.def("GetEncondingParams", &PlaintextImpl::GetEncondingParams)
-        .def("Encode", &PlaintextImpl::Encode)
-        .def("Decode", &PlaintextImpl::Decode)
-        .def("GetCKKSPackedValue", &PlaintextImpl::GetCKKSPackedValue)
+        .def("GetScalingFactor", &PlaintextImpl::GetScalingFactor,
+            ptx_GetScalingFactor_docs)
+        .def("SetScalingFactor", &PlaintextImpl::SetScalingFactor,
+            ptx_SetScalingFactor_docs,
+            py::arg("sf"))
+        .def("GetLength", &PlaintextImpl::GetLength,
+            ptx_GetLength_docs)
+        .def("GetSchemeID", &PlaintextImpl::GetSchemeID,
+            ptx_GetSchemeID_docs)
+        .def("SetLength", &PlaintextImpl::SetLength,
+            ptx_SetLength_docs,
+            py::arg("newSize"))
+        .def("IsEncoded", &PlaintextImpl::IsEncoded,
+            ptx_IsEncoded_docs)
+        .def("GetLogPrecision", &PlaintextImpl::GetLogPrecision,
+            ptx_GetLogPrecision_docs)
+        .def("Encode", &PlaintextImpl::Encode,
+            ptx_Encode_docs)
+        .def("Decode", &PlaintextImpl::Decode,
+            ptx_Decode_docs)
+        .def("GetCKKSPackedValue", &PlaintextImpl::GetCKKSPackedValue,
+            ptx_GetCKKSPackedValue_docs)
         .def("__repr__", [](const PlaintextImpl &p)
              {
         std::stringstream ss;
@@ -505,8 +776,11 @@ void bind_ciphertext(py::module &m)
        // .def(py::self + py::self);
     // .def("GetDepth", &CiphertextImpl<DCRTPoly>::GetDepth)
     // .def("SetDepth", &CiphertextImpl<DCRTPoly>::SetDepth)
-     .def("GetLevel", &CiphertextImpl<DCRTPoly>::GetLevel)
-     .def("SetLevel", &CiphertextImpl<DCRTPoly>::SetLevel);
+     .def("GetLevel", &CiphertextImpl<DCRTPoly>::GetLevel,
+        ctx_GetLevel_docs)
+     .def("SetLevel", &CiphertextImpl<DCRTPoly>::SetLevel,
+        ctx_SetLevel_docs,
+        py::arg("level"));
     // .def("GetHopLevel", &CiphertextImpl<DCRTPoly>::GetHopLevel)
     // .def("SetHopLevel", &CiphertextImpl<DCRTPoly>::SetHopLevel)
     // .def("GetScalingFactor", &CiphertextImpl<DCRTPoly>::GetScalingFactor)
@@ -532,10 +806,10 @@ PYBIND11_MODULE(openfhe, m)
     bind_parameters<CryptoContextBFVRNS>(m,"CCParamsBFVRNS");
     bind_parameters<CryptoContextBGVRNS>(m,"CCParamsBGVRNS");
     bind_parameters<CryptoContextCKKSRNS>(m,"CCParamsCKKSRNS");
-    bind_crypto_context(m);
-    bind_keys(m);
     bind_encodings(m);
     bind_ciphertext(m);
+    bind_keys(m);
+    bind_crypto_context(m);
     bind_serialization(m);
     bind_schemes(m);
     // binfhe library

+ 10 - 2
src/binfhe_bindings.cpp

@@ -5,6 +5,7 @@
 #include "binfhe_bindings.h"
 #include "binfhecontext.h"
 #include "binfhecontext_wrapper.h"
+#include "binfhecontext_docs.h"
 
 using namespace lbcrypto;
 namespace py = pybind11;
@@ -105,25 +106,32 @@ void bind_binfhe_context(py::module &m)
     py::class_<BinFHEContext>(m, "BinFHEContext")
         .def(py::init<>())
         .def("GenerateBinFHEContext", static_cast<void (BinFHEContext::*)(BINFHE_PARAMSET, BINFHE_METHOD)>(&BinFHEContext::GenerateBinFHEContext),
+             binfhe_GenerateBinFHEContext_parset_docs,
              py::arg("set"), 
              py::arg("method") = GINX)
-        .def("KeyGen", &BinFHEContext::KeyGen)
-        .def("BTKeyGen", &BinFHEContext::BTKeyGen)
+        .def("KeyGen", &BinFHEContext::KeyGen,
+            binfhe_KeyGen_docs)
+        .def("BTKeyGen", &BinFHEContext::BTKeyGen,
+            binfhe_BTKeyGen_docs)
         .def("Encrypt", &binfhe_EncryptWrapper,
+             binfhe_Encrypt_docs,
              py::arg("sk"),
              py::arg("m"),
              py::arg("output") = BOOTSTRAPPED,
              py::arg("p") = 4, 
              py::arg("mod") = 0)
         .def("Decrypt",&binfhe_DecryptWrapper,
+             binfhe_Decrypt_docs,
              py::arg("sk"),
              py::arg("ct"),
              py::arg("p") = 4)
         .def("EvalBinGate",&BinFHEContext::EvalBinGate,
+             binfhe_EvalBinGate_docs,
              py::arg("gate"),
              py::arg("ct1"),
              py::arg("ct2"))
         .def("EvalNOT",&BinFHEContext::EvalNOT,
+             binfhe_EvalNOT_docs,
              py::arg("ct"));
             
 }

+ 2 - 2
src/pke/examples/advanced-real-numbers-128.py

@@ -1,6 +1,6 @@
 from openfhe import *
 import time # to enable TIC-TOC timing measurements
-
+ 
 def automatic_rescale_demo(scal_tech):
     if(scal_tech == ScalingTechnique.FLEXIBLEAUTO):
         print("\n\n\n ===== FlexibleAutoDemo =============\n") 
@@ -383,7 +383,7 @@ def main():
         fast_rotation_demo1()
         fast_rotation_demo2()
     else:
-        print("This demo only runs for 128-bit CKKS.\n")
+        print("This demo only runs for 128-bit CKKS.\nIf you want to test it please reinstall the OpenFHE C++ with the flag -DNATIVE_INT=128, then reinstall OpenFHE-Python.")
 
 if __name__ == "__main__":
     main()

+ 1 - 1
src/pke/examples/advanced-real-numbers.py

@@ -209,7 +209,7 @@ def fast_rotation_demo1():
     parameters = CCParamsCKKSRNS()
     parameters.SetMultiplicativeDepth(5)
     parameters.SetScalingModSize(50)
-    parameters.SetBatchSize(batchSize)
+    parameters.SetBatchSize(batch_size)
 
     cc = GenCryptoContext(parameters)
 

+ 8 - 4
src/pke/examples/function-evaluation.py

@@ -54,8 +54,12 @@ def eval_function_example():
     parameters.SetSecurityLevel(SecurityLevel.HEStd_NotSet)
     parameters.SetRingDim(1 << 10)
 
-    scaling_mod_size = 59
-    first_mod_size = 60
+    if get_native_int() == 128:
+        scaling_mod_size = 78
+        first_mod_size = 89
+    else:
+        scaling_mod_size = 50
+        first_mod_size = 60
 
     parameters.SetScalingModSize(scaling_mod_size)
     parameters.SetFirstModSize(first_mod_size)
@@ -78,8 +82,8 @@ def eval_function_example():
     plaintext = cc.MakeCKKSPackedPlaintext(input)
     ciphertext = cc.Encrypt(key_pair.publicKey, plaintext)
 
-    lower_bound = 1
-    upper_bound = 9
+    lower_bound = 0
+    upper_bound = 10
     result = cc.EvalChebyshevFunction(math.sqrt,ciphertext, lower_bound, upper_bound, poly_degree)
 
     plaintext_dec = cc.Decrypt(result, key_pair.secretKey)

+ 1 - 1
src/pke/examples/iterative-ckks-bootstrapping.py

@@ -60,7 +60,7 @@ def iterative_bootstrap_example():
     # Step 2: Precomputations for bootstrapping
     # We use a sparse packing
     num_slots = 8
-    cryptocontext.EvalBootstrapSetup(levelBudget, bsgs_dim, num_slots)
+    cryptocontext.EvalBootstrapSetup(level_budget, bsgs_dim, num_slots)
 
     # Step 3: Key generation
     key_pair = cryptocontext.KeyGen()