Expand description
An implementation of the (additive homomorphism only) Fan-Vercauteren (FV) lattice-based homomorphic encryption scheme.
Overview
Homomorphic encryption supports operations on encrypted data without knowing the decryption key.
In order to use lattice-based homomorphic encryption, we first need to decide on the scheme to use and set up the parameters, including the polynomial degree (n) and the modulus (q).
Currently, we only support one scheme (FV) and one set of parameters, corresponding to a polynomial degree of 2048 and a 54-bit prime modulus.
let scheme = cupcake::default();Setup
In order to encrypt and decrypt data, we needs to generate a keypair, i.e. a secret key and a public key.
let scheme = cupcake::default();
use cupcake::traits::{SKEncryption, PKEncryption};
let (pk, sk) = scheme.generate_keypair();The public key can be used for encryption and the secret key can be used for encryption or decryption.
Encryption and Decryption
The library currently supports one plaintext type, which is vec<u8> of fixed size n. We can encrypt a vector under a public key like so
let v = vec![1; scheme.n];
let ct = scheme.encrypt(&v, &pk);Then, the ciphertext ct can be decrypted using the secret key:
let w = scheme.decrypt(&ct, &sk);
assert_eq!(v, w);Homomorphic Operations
We can encrypt two vectors and add up the resulting ciphertexts.
use cupcake::traits::{AdditiveHomomorphicScheme};
let z1 = vec![1; scheme.n];
let mut ctz1 = scheme.encrypt(&z1, &pk);
let z2 = vec![2; scheme.n];
let ctz2 = scheme.encrypt(&z2, &pk);
scheme.add_inplace(&mut ctz1, &ctz2);
// Now ctz1 should decrypt to vec![3; scheme.n];
let expected = vec![3; scheme.n];
let actual = scheme.decrypt(&ctz1, &sk);
assert_eq!(actual, expected);Alternatively, we can add a plaintext vector into a ciphertext
let z = vec![1; scheme.n];
let mut ctz = scheme.encrypt(&z, &pk);
let p = vec![4; scheme.n];
scheme.add_plain_inplace(&mut ctz, &p);
// Now ctz should decrypt to vec![5; scheme.n]
let expected = vec![5; scheme.n];
let actual = scheme.decrypt(&ctz, &sk);
assert_eq!(actual, expected);Rerandomization
Furthermore, you can rerandomize a ciphertext using the public key. The output is another ciphertext which will be still decrypt to the same plaintext, but cannot be linked to the input.
let mu = vec![1; scheme.n];
let mut ct = scheme.encrypt(&mu, &pk);
scheme.rerandomize(&mut ct, &pk);
// The new ct should still decrypt to mu.
let actual = scheme.decrypt(&ct, &sk);
let expected = mu;
assert_eq!(actual, expected);Modules
Structs
(Additive only version of) the Fan-Vercauteren homomoprhic encryption scheme.
SecretKey type