pub struct Ciphertext { /* private fields */ }
Expand description

A BFV12 Ciphertext

  • c_0 = [p_0 * u + e_1 + delta * m]_q
  • c_1 = [p_1 * u + e_2]_q
  • q = the ciphertext modulus
  • t = the plaintext modulus

Implementations

Decrypt a ciphertext to recover a plaintext, given a secret key

use bfv12::{Plaintext, SecretKey};
let pt = Plaintext::new(vec![0, 1, 2, 3], t);

let secret_key = SecretKey::generate(degree, &mut rng);
let public_key = secret_key.public_key_gen(q, std_dev, &mut rng);

let ct = pt.encrypt(&public_key, std_dev, &mut rng);
let decrypted = ct.decrypt(&secret_key);

assert_eq!(decrypted, pt);

Trait Implementations

Add two ciphertexts. They can be of different degrees.

let secret_key = SecretKey::generate(degree, &mut rng);
let public_key = secret_key.public_key_gen(q, std_dev, &mut rng);

let pt_1 = Plaintext::rand(degree, t, &mut rng);
let pt_2 = Plaintext::rand(degree, t, &mut rng);
let ct_1 = pt_1.encrypt(&public_key, std_dev, &mut rng);
let ct_2 = pt_2.encrypt(&public_key, std_dev, &mut rng);

// Add the ciphertexts: ct_1 + ct_2
let add_ct = ct_1 + ct_2;

// Decrypt the result of the addition
let add_pt = add_ct.decrypt(&secret_key);

// Compare the expected output to the decrypted output
let expected_pt = (pt_1.poly() + pt_2.poly()) % (t, degree);
assert_eq!(add_pt.poly(), expected_pt)

The resulting type after applying the + operator.

Performs the + operation. Read more

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Multiply two ciphertexts, using Relinearization Version 1. Since multiplication requires a relinearization key, you must multiply a ciphertext with a tuple of (Ciphertext, &RelinearizationKey1). The type of the relinearization key determines whether the multiplication uses Relinearization Version 1 or 2.

let secret_key = SecretKey::generate(degree, &mut rng);
let public_key = secret_key.public_key_gen(q, std_dev, &mut rng);
let rlk_1 = secret_key.relin_key_gen_1(q, std_dev, &mut rng, rlk_base);

let pt_1 = Plaintext::rand(degree, t, &mut rng);
let pt_2 = Plaintext::rand(degree, t, &mut rng);
let ct_1 = pt_1.encrypt(&public_key, std_dev, &mut rng);
let ct_2 = pt_2.encrypt(&public_key, std_dev, &mut rng);

// Multiply the ciphertexts: ct_1 * ct_2
let mul_ct = ct_1 * (ct_2, &rlk_1);

// Decrypt the result of the multiplication
let mul_pt = mul_ct.decrypt(&secret_key);

// Compare the expected output to the decrypted output
let expected_pt = (pt_1.poly() * pt_2.poly()) % (t, degree);
assert_eq!(mul_pt.poly(), expected_pt)

The resulting type after applying the * operator.

Performs the * operation. Read more

Multiply two ciphertexts, using Relinearization Version 2. Since multiplication requires a relinearization key, you must multiply a ciphertext with a tuple of (Ciphertext, &RelinearizationKey2). The type of the relinearization key determines whether the multiplication uses Relinearization Version 1 or 2.

let secret_key = SecretKey::generate(degree, &mut rng);
let public_key = secret_key.public_key_gen(q, std_dev, &mut rng);

// p = the amount to scale the modulus, during modulus switching
// Technically p should be >= q^3 for security (see paper discussion on Relinearization Version 2),
// but setting p = q^3 results in an overflow when taking p * q so we will test with a smaller p.
let p = 2_i64.pow(13) * q;
let rlk_2 = secret_key.relin_key_gen_2(q, std_dev, &mut rng, p);

let pt_1 = Plaintext::rand(degree, t, &mut rng);
let pt_2 = Plaintext::rand(degree, t, &mut rng);
let ct_1 = pt_1.encrypt(&public_key, std_dev, &mut rng);
let ct_2 = pt_2.encrypt(&public_key, std_dev, &mut rng);

// Multiply the ciphertexts: ct_1 * ct_2
let mul_ct = ct_1 * (ct_2, &rlk_2);

// Decrypt the result of the multiplication
let mul_pt = mul_ct.decrypt(&secret_key);

// Compare the expected output to the decrypted output
let expected_pt = (pt_1.poly() * pt_2.poly()) % (t, degree);
assert_eq!(mul_pt.poly(), expected_pt)

The resulting type after applying the * operator.

Performs the * operation. Read more

Take the negation of a ciphertext.

let secret_key = SecretKey::generate(degree, &mut rng);
let public_key = secret_key.public_key_gen(q, std_dev, &mut rng);

let pt = Plaintext::rand(degree, t, &mut rng);
let ct = pt.encrypt(&public_key, std_dev, &mut rng);

// Negate: -ct
let neg_ct = -ct;

// Decrypt the result of the negation
let neg_pt = neg_ct.decrypt(&secret_key);

// Compare the expected output to the decrypted output
let expected_pt = -pt.poly() % (t, degree);
assert_eq!(neg_pt.poly(), expected_pt)

The resulting type after applying the - operator.

Performs the unary - operation. Read more

Subtract one ciphertext from another. They can be of different degrees.

let secret_key = SecretKey::generate(degree, &mut rng);
let public_key = secret_key.public_key_gen(q, std_dev, &mut rng);

let pt_1 = Plaintext::rand(degree, t, &mut rng);
let pt_2 = Plaintext::rand(degree, t, &mut rng);
let ct_1 = pt_1.encrypt(&public_key, std_dev, &mut rng);
let ct_2 = pt_2.encrypt(&public_key, std_dev, &mut rng);

// Subtract: ct_1 - ct_2
let sub_ct = ct_1 - ct_2;

// Decrypt the result of the subtraction
let sub_pt = sub_ct.decrypt(&secret_key);

// Compare the expected output to the decrypted output
let expected_pt = (pt_1.poly() - pt_2.poly()) % (t, degree);
assert_eq!(sub_pt.poly(), expected_pt)

The resulting type after applying the - operator.

Performs the - operation. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.