Browse Source

docs: installation, types and algorithms; int and real examples

Alexandra Mirzuitova 1 year ago
parent
commit
49791f4c1b

+ 0 - 7
docs/source/api.rst

@@ -1,7 +0,0 @@
-API
-===
-
-.. autosummary::
-   :toctree: generated
-
-   lumache

+ 33 - 0
docs/source/base_types_and_alg.rst

@@ -0,0 +1,33 @@
+Base types and algorithms
+=========================
+
+There are a couple of base types used around all the FHE-enabled applications. You can check this section or jump directly into our examples and figure out everything through experience.
+
+Remember: if you have any questions not covered on this page - feel free to ping us on our `Discord server <https://discord.com/invite/NfhXwyr9M5>`_.
+
+Cryptography schemes supported
+-------------------------------
+
+We currently support three so-called PKE schemes:
+
+- CKKS
+- BFV
+- BGV
+
+Many of our methods and algorithms contain the suffix referring to the scheme used. This section provides examples.
+
+Params
+------
+
+The Params policy type stores flags and parameters for the FHE algorithms to use.
+
+There are different ways to generate a Params type instance, but the main way is to create a mutable object by calling ``GetParams%scheme_name%`` and setting the options after that. For the CKKS scheme, it will be ``GetParamsCKKSRNS``.
+
+CryptoContext
+-------------
+
+CryptoContext type, as its name stands, stores the metadata of your FHE context. You usually create its instance using one of the following functions:
+
+- By generating the CryptoContext directly - ``ffi::GenCryptoContextByParamsCKKSRNS``
+- By deserializing a CryptoContext generated somewhere else - ``ffi::DeserializeCryptoContextFromFile``
+

+ 20 - 14
docs/source/index.rst

@@ -1,12 +1,20 @@
 Welcome to OpenFHE Rust wrapper's documentation!
 ===================================
 
+OpenFHE
+--------
+
+Fully Homomorphic Encryption (FHE) is a powerful cryptographic primitive that enables performing computations over encrypted data without having access to the secret key.
+OpenFHE is an open-source FHE library that includes efficient implementations of all common FHE schemes:
+  - Brakerski/Fan-Vercauteren (BFV) scheme for integer arithmetic
+  - Brakerski-Gentry-Vaikuntanathan (BGV) scheme for integer arithmetic
+  - Cheon-Kim-Kim-Song (CKKS) scheme for real-number arithmetic (includes approximate bootstrapping)
+  - Ducas-Micciancio (DM/FHEW) and Chillotti-Gama-Georgieva-Izabachene (CGGI/TFHE), and Lee-Micciancio-Kim-Choi-Deryabin-Eom-Yoo (LMKCDEY) schemes for evaluating Boolean circuits and arbitrary functions over larger plaintext spaces using lookup tables
+
 About OpenFHE-rs
 ================
 
-☀️ *OpenFHE-rs is a joint project by `FairMath <https://fairmath.xyz/>`__ & `OpenFHE <https://www.openfhe.org/>`__.*
-
----
+OpenFHE-rs is a joint project by `Fair Math <https://fairmath.xyz/>`_ & `OpenFHE <https://www.openfhe.org/>`_
 
 .. image:: https://img.shields.io/discord/1163764915803279360?logo=discord&label=Fair%20Math
    :target: https://discord.com/invite/NfhXwyr9M5
@@ -14,25 +22,23 @@ About OpenFHE-rs
 .. image:: https://img.shields.io/twitter/follow/FairMath
    :target: https://twitter.com/FairMath
 
----
+.. note::
+
+   🔔 Keep in mind that the library is WIP and may contain some unpolished interfaces. If you encounter any issues or have any suggestions, feel free to ping us on our Discord server or open a new issue in the `GitHub repository <https://github.com/fairmath/openfhe-rs/tree/master>`_.
 
 OpenFHE-rs is a Rust interface for the OpenFHE library, which is renowned for its comprehensive suite of Fully Homomorphic Encryption (FHE) schemes, all implemented in C++. By providing a Rust wrapper for OpenFHE, we aim to make these advanced FHE capabilities easily accessible to Rust developers.
 
 Whether you're developing secure data processing applications or privacy-focused tools, OpenFHE-rs enables you to leverage the powerful encryption technologies of OpenFHE seamlessly within your Rust projects.
 
-
-
-Check out the :doc:`intro` section for further information, including installation instructions.
-
-.. note::
-
-   🔔 *Keep in mind that the library is WIP and may contain some unpolished interfaces. If you encounter any issues or have any suggestions, feel free to ping us on our Discord server or open a new issue in the `GitHub repository <https://github.com/fairmath/openfhe-rs/tree/master>`__.*
+Check out the :doc:`intro` section for quick start information, including installation instructions.
 
 Contents
 --------
 
 .. toctree::
 
-   usage
-   api
-   examples
+   intro
+   limitations
+   base_types_and_alg
+   simple_integers
+   simple_real_numbers

+ 9 - 12
docs/source/intro.rst

@@ -1,14 +1,11 @@
-
 About OpenFHE-rs
 ================
 
-☀️ *OpenFHE-rs is a joint project by `FairMath <https://fairmath.xyz/>`__ & `OpenFHE <https://www.openfhe.org/>`__.*
-
----
+OpenFHE-rs is a joint project by `Fair Math <https://fairmath.xyz/>`_ & `OpenFHE <https://www.openfhe.org/>`_
 
-🔔 *Keep in mind that the library is WIP and may contain some unpolished interfaces. If you encounter any issues or have any suggestions, feel free to ping us on our Discord server or open a new issue in the `GitHub repository <https://github.com/fairmath/openfhe-rs/tree/master>`__.*
+.. note::
 
----
+   🔔 Keep in mind that the library is WIP and may contain some unpolished interfaces. If you encounter any issues or have any suggestions, feel free to ping us on our Discord server or open a new issue in the `GitHub repository <https://github.com/fairmath/openfhe-rs/tree/master>`_.
 
 OpenFHE-rs is a Rust interface for the OpenFHE library, which is renowned for its comprehensive suite of Fully Homomorphic Encryption (FHE) schemes, all implemented in C++. By providing a Rust wrapper for OpenFHE, we aim to make these advanced FHE capabilities easily accessible to Rust developers.
 
@@ -44,7 +41,7 @@ Installation process
 Core OpenFHE library installation
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-To build and install the OpenFHE library, follow the steps below or refer to `OpenFHE's installation documentation <https://openfhe-development.readthedocs.io/en/latest/sphinx_rsts/intro/installation/installation.html>`__.
+To build and install the OpenFHE library, follow the steps below or refer to `OpenFHE's installation documentation <https://openfhe-development.readthedocs.io/en/latest/sphinx_rsts/intro/installation/installation.html>`_.
 
 1. Clone the repository
 
@@ -75,7 +72,7 @@ To build and install the OpenFHE library, follow the steps below or refer to `Op
 Configuring your project to use the crate
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-To use the OpenFHE crate in your Rust project, add it as a dependency from `crates.io <https://crates.io/crates/openfhe>`__:
+To use the OpenFHE crate in your Rust project, add it as a dependency from `crates.io <https://crates.io/crates/openfhe>`_:
 
 .. code-block:: bash
 
@@ -101,12 +98,12 @@ You also need to add a small piece of code for the core dependencies' configurat
 Template repository
 ~~~~~~~~~~~~~~~~~~~
 
-Instead of doing it manually, you can start your project by forking our `template repository <https://github.com/fairmath/openfhe-rs-template/tree/main>`__.
+Instead of doing it manually, you can start your project by forking our `template repository <https://github.com/fairmath/openfhe-rs-template/tree/main>`_.
 
 Custom crate installation from the source
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-You can adjust the installation process by building the crate manually. In that case, you need to clone the Fair Math's `openfhe-rs <https://github.com/fairmath/openfhe-rs>`__ repo to your local machine and build it:
+You can adjust the installation process by building the crate manually. In that case, you need to clone the Fair Math's `openfhe-rs <https://github.com/fairmath/openfhe-rs>`_ repo to your local machine and build it:
 
 1. Clone the repository
 
@@ -139,10 +136,10 @@ You can adjust the installation process by building the crate manually. In that
 Contributing
 ============
 
-Contributions are always welcome! If you find bugs, have feature requests, or want to contribute code, please open an issue or pull request on the `GitHub repository <https://github.com/fairmath/openfhe-rs/tree/master>`__.
+Contributions are always welcome! If you find bugs, have feature requests, or want to contribute code, please open an issue or pull request on the `GitHub repository <https://github.com/fairmath/openfhe-rs/tree/master>`_.
 
 License
 =======
 
-`OpenFHE-rs` is licensed under the **BSD 2-Clause License**. See the `LICENSE <LICENSE>`__ file for more details.
+`OpenFHE-rs` is licensed under the **BSD 2-Clause License**. See the `LICENSE <LICENSE>`_ file for more details.
 

+ 21 - 0
docs/source/limitations.rst

@@ -0,0 +1,21 @@
+Limitations
+===========
+
+OpenFHE
+-------
+
+See the `Security Notes for Homomorphic Encryption <https://openfhe-development.readthedocs.io/en/latest/sphinx_rsts/intro/security.html>`_ in OpenFHE's documentation.
+
+Rust wrapper
+------------
+
+The library is WIP and may contain some unpolished interfaces. If you struggle with anything or have suggestions, feel free to ping us on our Discord server or open a new issue in the `GitHub repository <https://github.com/fairmath/openfhe-rs/tree/master>`_.
+
+At the moment, only a certain set of OpenFHE functionality has been implemented.
+
+We use the `CXX crate <https://cxx.rs/>`_ for our Rust binding to reduce the amount of abstraction levels. OpenFHE types are represented as opaque types on the Rust side using `cxx::UniquePtr <https://docs.rs/cxx/latest/cxx/struct.UniquePtr.html>`_ from the CXX crate. Instead of the usual `std::vec <https://doc.rust-lang.org/std/vec/>`_, we use `cxx::CxxVector <https://docs.rs/cxx/latest/cxx/struct.CxxVector.html>`_ for primitive types, and also `CxxVector<ComplexPair>` for representing `std::vector<std::complex<double>>` type.
+
+The main difference lies in the current `cxx::CxxVector` supported functional, limited compared to `std::vector`, e.g. you need to init `cxx::CxxVector` element by element. Since `cxx` currently does not support `cxx::CxxVector` of opaque types, we are using a separate type for each vector of opaque type. Since `cxx` currently does not support alternatives for `std::unordered_map` and `std::map`, we are using separate types for them. The implementations of these types are very simple because we are planning to switch `cxx` variants further. But before switching these types can be extended to support basic functional of `std::vector`, `std::map` and `std::unordered_map` if required.
+
+Since Rust does not support default parameters and function overloading, default parameters are mentioned in comments after the corresponding parameter name, and overloaded functions are represented by slightly different names. Calling member functions of generated null types (generated by GenNull... functions) results in undefined behavior. Since `CXX` crate has limited support for function pointers - only functions without a return type are supported) - EvalChebychevFunction expects `fn(f64, ret: &mut f64)` as the callable object.
+

+ 121 - 0
docs/source/simple_integers.rst

@@ -0,0 +1,121 @@
+Homomorphic additions, multiplications, and rotations for vectors of integers via BFV
+=======================================================================================
+
+Overview
+--------
+
+This Rust example demonstrates basic homomorphic encryption operations such as addition, multiplication, and rotation on vectors of integers using the BFVrns3 scheme provided by the `openfhe` library. The example walks through the setup of cryptographic parameters, key generation, encryption of plaintext vectors, performing homomorphic operations, and decrypting the results. The example for this code is located in :code:`examples/simple_integers.rs`.
+
+Code breakdown
+--------------
+
+Importing libraries
+~~~~~~~~~~~~~~~~~~
+
+We start by importing the necessary libraries and modules:
+
+.. code-block:: rust
+
+    use openfhe::cxx::{CxxVector};
+    use openfhe::ffi as ffi;
+
+The code example
+~~~~~~~~~~~~~~~~
+
+The `main` function contains the entire workflow for setting up the BFV scheme, performing encryption, executing homomorphic operations, and decrypting the results.
+
+Generating Parameters
+~~~~~~~~~~~~~~~~~~~~
+
+We define the cryptographic parameters for the BFV scheme, namely plaintext modulus and multiplicative depth.
+
+.. code-block:: rust
+
+    let mut _cc_params_bfvrns = ffi::GenParamsBFVRNS();
+    _cc_params_bfvrns.pin_mut().SetPlaintextModulus(65537);
+    _cc_params_bfvrns.pin_mut().SetMultiplicativeDepth(2);
+
+Creating Crypto Context
+~~~~~~~~~~~~~~~~~~~~~~~
+
+We create a crypto context based on the defined parameters and enable necessary features.
+
+.. code-block:: rust
+
+    let _cc = ffi::GenCryptoContextByParamsBFVRNS(&_cc_params_bfvrns);
+    _cc.Enable(ffi::PKESchemeFeature::PKE);
+    _cc.Enable(ffi::PKESchemeFeature::KEYSWITCH);
+    _cc.Enable(ffi::PKESchemeFeature::LEVELEDSHE);
+
+Key Generation
+~~~~~~~~~~~~~~
+
+We generate the necessary keys for encryption, including evaluation keys for multiplication and rotation.
+
+.. code-block:: rust
+
+    let _key_pair = _cc.KeyGen();
+    _cc.EvalMultKeyGen(&_key_pair.GetPrivateKey());
+
+    let mut _index_list = CxxVector::<i32>::new();
+    _index_list.pin_mut().push(1);
+    _index_list.pin_mut().push(2);
+    _index_list.pin_mut().push(-1);
+    _index_list.pin_mut().push(-2);
+    _cc.EvalRotateKeyGen(&_key_pair.GetPrivateKey(), &_index_list, &ffi::GenNullPublicKey());
+
+Plaintext Vector Creation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: rust
+
+    let mut _vector_of_ints_1 = CxxVector::<i64>::new();
+    _vector_of_ints_1.pin_mut().push(1);
+    _vector_of_ints_1.pin_mut().push(2);
+    ...
+    let _plain_text_1 = _cc.MakePackedPlaintext(&_vector_of_ints_1, 1, 0);
+
+Encrypting Plaintext Vectors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We encrypt the plaintext vectors using the generated public key.
+
+.. code-block:: rust
+
+    let _cipher_text_1 = _cc.EncryptByPublicKey(&_key_pair.GetPublicKey(), &_plain_text_1);
+
+Performing Homomorphic Operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We perform various homomorphic operations on the encrypted data, including addition, multiplication, and rotations.
+
+.. code-block:: rust
+
+    let _cipher_text_add_1_2 = _cc.EvalAddByCiphertexts(&_cipher_text_1, &_cipher_text_2);
+    let _cipher_text_mult_result = _cc.EvalMultByCiphertexts(&_cipher_text_mul_1_2, &_cipher_text_3);
+    let _cipher_text_rot_1 = _cc.EvalRotate(&_cipher_text_1, 1);
+
+Decrypting and Printing Results
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Finally, we decrypt the results of the homomorphic computations and print them.
+
+.. code-block:: rust
+
+    let mut _plain_text_add_result = ffi::GenNullPlainText();
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_cipher_text_add_result, _plain_text_add_result.pin_mut());
+    println!("Plaintext #1: {}", _plain_text_1.GetString());
+
+Running the example
+~~~~~~~~~~~~~~~~~~~~
+
+1. Ensure the `openfhe-rs` library is installed and properly configured, see the :doc:`intro` section.
+2. Go to the `examples` directory and make sure that the needed example is there - `simple_integers.rs`.
+3. Compile and run the Rust file:
+
+.. code-block:: sh
+
+    rustc simple_integers.rs -o simple_integers
+    ./simple_integers
+
+This should output the results of the homomorphic computations to the console.

+ 195 - 0
docs/source/simple_real_numbers.rst

@@ -0,0 +1,195 @@
+Homomorphic additions, multiplications, and rotations for vectors of real numbers via CKKS
+===========================================================================================
+
+Overview
+--------
+
+Homomorphic encryption allows computations on encrypted data without decrypting it. The CKKS (Cheon-Kim-Kim-Song) scheme supports approximate arithmetic operations on encrypted data, making it suitable for real number calculations.
+
+The example walks through the setup of cryptographic parameters, key generation, encryption of plaintext vectors, performing homomorphic operations, and decrypting the results. The example for this code is located in :code:`examples/simple_real_numbers.rs`.
+
+Code breakdown
+--------------
+
+Importing libraries
+~~~~~~~~~~~~~~~~~~
+
+We start by importing the necessary libraries and modules:
+
+.. code-block:: rust
+
+    use openfhe::cxx::{CxxVector, SharedPtr};
+    use openfhe::ffi as ffi;
+
+The code example
+~~~~~~~~~~~~~~~~
+
+The :code:`main` function contains the entire workflow for setting up the CKKS scheme, performing encryption, executing homomorphic operations, and decrypting the results.
+
+.. code-block:: rust
+
+    fn main() {
+        // Define cryptographic parameters for CKKS
+        let _mult_depth: u32 = 1;
+        let _scale_mod_size: u32 = 50;
+        let _batch_size: u32 = 8;
+
+Generating Parameters
+~~~~~~~~~~~~~~~~~~~~
+
+We define the cryptographic parameters for the CKKS scheme, including multiplicative depth, scaling modulus size, and batch size.
+
+.. code-block:: rust
+
+    // Generate parameters for CKKS scheme
+    let mut _cc_params_ckksrns = ffi::GenParamsCKKSRNS();
+    _cc_params_ckksrns.pin_mut().SetMultiplicativeDepth(_mult_depth);
+    _cc_params_ckksrns.pin_mut().SetScalingModSize(_scale_mod_size);
+    _cc_params_ckksrns.pin_mut().SetBatchSize(_batch_size);
+
+Creating Crypto Context
+~~~~~~~~~~~~~~~~~~~~~~~
+
+We create a crypto context based on the defined parameters and enable necessary features.
+
+.. code-block:: rust
+
+    // Create crypto context based on parameters
+    let _cc = ffi::GenCryptoContextByParamsCKKSRNS(&_cc_params_ckksrns);
+    _cc.Enable(ffi::PKESchemeFeature::PKE);
+    _cc.Enable(ffi::PKESchemeFeature::KEYSWITCH);
+    _cc.Enable(ffi::PKESchemeFeature::LEVELEDSHE);
+
+    // Outputing the ring dimension for clarity
+    println!("CKKS scheme is using ring dimension {}\n", _cc.GetRingDimension());
+
+Key Generation
+~~~~~~~~~~~~~~
+
+We generate the necessary keys for encryption, including evaluation keys for multiplication and rotation.
+
+.. code-block:: rust
+
+    // Key generation
+    let _key_pair = _cc.KeyGen();
+    _cc.EvalMultKeyGen(&_key_pair.GetPrivateKey());
+
+    // Generate rotation keys
+    let mut _index_list = CxxVector::<i32>::new();
+    _index_list.pin_mut().push(1);
+    _index_list.pin_mut().push(-2);
+    _cc.EvalRotateKeyGen(&_key_pair.GetPrivateKey(), &_index_list, &ffi::GenNullPublicKey());
+
+Creating Input Vectors
+~~~~~~~~~~~~~~~~~~~~~~
+
+We create two input vectors for the demonstration.
+
+.. code-block:: rust
+
+    // Create input vectors
+    let mut _x_1 = CxxVector::<f64>::new();
+    _x_1.pin_mut().push(0.25);
+    ...
+    _x_1.pin_mut().push(5.0);
+
+    let mut _x_2 = CxxVector::<f64>::new();
+    _x_2.pin_mut().push(5.0);
+    ...
+    _x_2.pin_mut().push(0.25);
+
+Creating Plaintext Objects
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We convert the input vectors into plaintext objects.
+
+.. code-block:: rust
+
+    // Create plaintext objects from vectors
+    let _p_txt_1 = _cc.MakeCKKSPackedPlaintext(&_x_1, 1, 0, SharedPtr::<ffi::DCRTPolyParams>::null(), 0);
+    let _p_txt_2 = _cc.MakeCKKSPackedPlaintext(&_x_2, 1, 0, SharedPtr::<ffi::DCRTPolyParams>::null(), 0);
+
+    // Outputing the vectors for clarity
+    println!("Input x1: {}", _p_txt_1.GetString());
+    println!("Input x2: {}", _p_txt_2.GetString());
+
+Encrypting Plaintext Vectors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We encrypt the plaintext vectors using the generated public key.
+
+.. code-block:: rust
+
+    // Encrypt plaintext vectors
+    let _c1 = _cc.EncryptByPublicKey(&_key_pair.GetPublicKey(), &_p_txt_1);
+    let _c2 = _cc.EncryptByPublicKey(&_key_pair.GetPublicKey(), &_p_txt_2);
+
+Performing Homomorphic Operations
+----------------------------------
+
+We perform various homomorphic operations on the encrypted data, including addition, subtraction, multiplication by a constant, multiplication of ciphertexts, and rotations.
+
+.. code-block:: rust
+
+    // Perform homomorphic operations
+    let _c_add = _cc.EvalAddByCiphertexts(&_c1, &_c2);
+    let _c_sub = _cc.EvalSubByCiphertexts(&_c1, &_c2);
+    let _c_scalar = _cc.EvalMultByCiphertextAndConst(&_c1, 4.0);
+    let _c_mul = _cc.EvalMultByCiphertexts(&_c1, &_c2);
+    let _c_rot_1 = _cc.EvalRotate(&_c1, 1);
+    let _c_rot_2 = _cc.EvalRotate(&_c1, -2);
+
+Decrypting and Printing Results
+--------------------------------
+
+Finally, we decrypt the results of the homomorphic computations and print them.
+
+.. code-block:: rust
+
+    // Prepare for decryption
+    let mut _result = ffi::GenNullPlainText();
+    println!("\nResults of homomorphic computations:");
+
+    // Decrypt and print results
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_c1, _result.pin_mut());
+    _result.SetLength(_batch_size.try_into().unwrap());
+    println!("x1 = {}Estimated precision in bits: {}", _result.GetString(), _result.GetLogPrecision());
+
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_c_add, _result.pin_mut());
+    _result.SetLength(_batch_size.try_into().unwrap());
+    println!("x1 + x2 = {}Estimated precision in bits: {}",_result.GetString(), _result.GetLogPrecision());
+
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_c_sub, _result.pin_mut());
+    _result.SetLength(_batch_size.try_into().unwrap());
+    println!("x1 - x2 = {}", _result.GetString());
+
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_c_scalar, _result.pin_mut());
+    _result.SetLength(_batch_size.try_into().unwrap());
+    println!("4 * x1 = {}", _result.GetString());
+
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_c_mul, _result.pin_mut());
+    _result.SetLength(_batch_size.try_into().unwrap());
+    println!("x1 * x2 = {}", _result.GetString());
+
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_c_rot_1, _result.pin_mut());
+    _result.SetLength(_batch_size.try_into().unwrap());
+    println!("\nIn rotations, very small outputs (~10^-10 here) correspond to 0's:");
+    println!("x1 rotate by 1 = {}", _result.GetString());
+
+    _cc.DecryptByPrivateKeyAndCiphertext(&_key_pair.GetPrivateKey(), &_c_rot_2, _result.pin_mut());
+    _result.SetLength(_batch_size.try_into().unwrap());
+    println!("x1 rotate by -2 = {}", _result.GetString());
+
+Running the example
+--------------------
+
+1. Ensure the `openfhe-rs` library is installed and properly configured, see the `Installation guide <../getting-started/installation.md>`_.
+2. Go to the `examples` directory and make sure that the needed example is there - `simple_real_numbers.rs`.
+3. Compile and run the Rust file:
+
+.. code-block:: sh
+
+    rustc simple_real_numbers.rs -o simple_real_numbers
+    ./simple_real_numbers
+
+This should output the results of the homomorphic computations to the console.

+ 0 - 34
docs/source/usage.rst

@@ -1,34 +0,0 @@
-Usage
-=====
-
-.. _installation:
-
-Installation
-------------
-
-To use Lumache, first install it using pip:
-
-.. code-block:: console
-
-   (.venv) $ pip install lumache
-
-Creating recipes
-----------------
-
-To retrieve a list of random ingredients,
-you can use the ``lumache.get_random_ingredients()`` function:
-
-.. autofunction:: lumache.get_random_ingredients
-
-The ``kind`` parameter should be either ``"meat"``, ``"fish"``,
-or ``"veggies"``. Otherwise, :py:func:`lumache.get_random_ingredients`
-will raise an exception.
-
-.. autoexception:: lumache.InvalidKindError
-
-For example:
-
->>> import lumache
->>> lumache.get_random_ingredients()
-['shells', 'gorgonzola', 'parsley']
-