B/FV homomorphic encryption scheme

This is a toy implementation of the B/FV homomorphic encryption scheme. The existing library is somewhat homomorphic: encryption, decryption, ciphertext addition and multiplication are supported, but only up to a certain multiplicative depth. For Fully Homomorphic Encryption (FHE), an implementation of bootstrapping is currently under development.

Example

The following example shows how to: 1. Generate secret, public, and relinearization keys 2. Encrypt plaintexts 3. Add and multiply ciphertexts 4. Decrypt ciphertexts

```rust use rand::SeedableRng; // Generate an RNG. Any Rng that implements RngCore + CryptoRng can be used. let mut rng = rand::rngs::StdRng::seedfromu64(18);

use bfv12::{SecretKey, Plaintext};

// Set the parameters for this instantiation of B/FV let t = 12; // Plaintext modulus let q = 65536; // Ciphertext modulus let stddev = 3.2; // Standard deviation for generating the error let degree = 4; // Degree of polynomials used for encoding and encrypting messages let rlkbase = (q as f64).log2() as i64; // The base for decomposition during relinearization

// Generate secret, public, and relinearization keys using the given parameters let secretkey = SecretKey::generate(degree, &mut rng); let publickey = secretkey.publickeygen(q, stddev, &mut rng); let rlk1 = secretkey.relinkeygen1(q, stddev, &mut rng, rlk_base);

// Generate random plaintexts let pt1 = Plaintext::rand(degree, t, &mut rng); let pt2 = Plaintext::rand(degree, t, &mut rng); let pt_3 = Plaintext::rand(degree, t, &mut rng);

// Encrypt the plaintexts let ct1 = pt1.encrypt(&publickey, stddev, &mut rng); let ct2 = pt2.encrypt(&publickey, stddev, &mut rng); let ct3 = pt3.encrypt(&publickey, stddev, &mut rng);

// Multiply and add the ciphertexts: ct1 * ct2 + ct3 // Note: multiplication requires the relinearization key let exprct = ct1 * (ct2, &rlk1) + ct3;

// Decrypt the result of the evaluation let exprpt = exprct.decrypt(&secret_key);

// Compare the expected output to the decrypted output let expectedpt = (pt1.poly() * pt2.poly() + pt3.poly()) % (t, degree); asserteq!(exprpt.poly(), expected_pt) ```

Links

Installation & Use

To use this library, you will need the Rust compiler. The compiler can be installed on linux and osx with the following command:

bash curl --tlsv1.2 -sSf https://sh.rustup.rs | sh

Other rust installation methods are available on the rust website.

Build with cargo build, run tests with cargo test.