1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
use crate::{
component_marker, Asym, AsymmetricComponents, Ciphertext, Context, Encryptor, Plaintext,
PublicKey, Result, SecretKey, Sym, SymAsym, SymmetricComponents,
};
use super::Tensor;
/// Encryptor that can encrypt multiple messages at once.
pub struct TensorEncryptor<T = ()> {
encryptor: Encryptor<T>,
typ: std::marker::PhantomData<T>,
}
impl<T> TensorEncryptor<T> {
/// Creates a new tensorEncryptor instance.
pub fn new(encryptor: Encryptor<T>) -> Self {
Self {
encryptor,
typ: std::marker::PhantomData,
}
}
}
impl TensorEncryptor {
/// Creates an Encryptor instance initialized with the specified SEALContext,
/// public key, and secret key.
///
/// * `ctx` - The SEALContext
/// * `publicKey` - The public key
/// * `secretKey` - The secret key
pub fn with_public_and_secret_key(
ctx: &Context,
public_key: &PublicKey,
secret_key: &SecretKey,
) -> Result<TensorEncryptor<SymAsym>> {
Ok(TensorEncryptor::new(Encryptor::with_public_and_secret_key(
ctx, public_key, secret_key,
)?))
}
/// Creates an Encryptor instance initialized with the specified SEALContext,
/// public key.
pub fn with_public_key(
ctx: &Context,
public_key: &PublicKey,
) -> Result<TensorEncryptor<Asym>> {
Ok(TensorEncryptor::new(Encryptor::with_public_key(
ctx, public_key,
)?))
}
/// Creates an Encryptor instance initialized with the specified SEALContext and
/// secret key.
pub fn with_secret_key(
ctx: &Context,
secret_key: &SecretKey,
) -> Result<TensorEncryptor<Sym>> {
Ok(TensorEncryptor::new(Encryptor::with_secret_key(
ctx, secret_key,
)?))
}
}
impl<T: component_marker::Asym> TensorEncryptor<T> {
/// Encrypts a plaintext with the public key and returns the ciphertext as
/// a serializable object.
///
/// The encryption parameters for the resulting ciphertext correspond to:
/// 1) in BFV, the highest (data) level in the modulus switching chain,
/// 2) in CKKS, the encryption parameters of the plaintext.
/// Dynamic memory allocations in the process are allocated from the memory
/// pool pointed to by the given MemoryPoolHandle.
///
/// * `plaintext_tensor` - The plaintext to encrypt.
pub fn encrypt(
&self,
plaintext_tensor: &Tensor<Plaintext>,
) -> Result<Tensor<Ciphertext>> {
plaintext_tensor
.map(|plaintext| self.encryptor.encrypt(plaintext))
.collect()
}
/// Encrypts a plaintext with the public key and returns the ciphertext as a
/// serializable object. Also returns the u and e values used in encrypting
/// the value.
///
/// The encryption parameters for the resulting ciphertext correspond to:
/// 1) in BFV, the highest (data) level in the modulus switching chain,
/// 2) in CKKS, the encryption parameters of the plaintext.
/// Dynamic memory allocations in the process are allocated from the memory
/// pool pointed to by the given MemoryPoolHandle.
///
/// * `plaintext_tensor` - The plaintext to encrypt.
pub fn encrypt_return_components(
&self,
plaintext_tensor: &Tensor<Plaintext>,
) -> Result<Tensor<(Ciphertext, AsymmetricComponents)>> {
plaintext_tensor
.map(|plaintext| self.encryptor.encrypt_return_components(plaintext))
.collect()
}
}
impl<T: component_marker::Sym> TensorEncryptor<T> {
/// Encrypts a plaintext with the secret key and returns the ciphertext as
/// a serializable object.
///
/// The encryption parameters for the resulting ciphertext correspond to:
/// 1) in BFV, the highest (data) level in the modulus switching chain,
/// 2) in CKKS, the encryption parameters of the plaintext.
/// Dynamic memory allocations in the process are allocated from the memory
/// pool pointed to by the given MemoryPoolHandle.
///
/// * `plaintext_tensor` - The plaintext to encrypt.
pub fn encrypt_symmetric(
&self,
plaintext_tensor: &Tensor<Plaintext>,
) -> Result<Tensor<Ciphertext>> {
plaintext_tensor
.map(|plaintext| self.encryptor.encrypt_symmetric(plaintext))
.collect()
}
/// Encrypts a plaintext with the secret key and returns the ciphertext as a
/// serializable object. Also returns the e (noise) and r (remainder) values used in
/// encrypting the value.
///
/// The encryption parameters for the resulting ciphertext correspond to:
/// 1) in BFV, the highest (data) level in the modulus switching chain,
/// 2) in CKKS, the encryption parameters of the plaintext.
/// pool pointed to by the given MemoryPoolHandle.
///
/// * `plaintext_tensor` - The plaintext to encrypt.
pub fn encrypt_symmetric_return_components(
&self,
plaintext_tensor: &Tensor<Plaintext>,
) -> Result<Tensor<(Ciphertext, SymmetricComponents)>> {
plaintext_tensor
.map(|plaintext| {
self.encryptor
.encrypt_symmetric_return_components(plaintext)
})
.collect()
}
}