concrete_boolean/server_key/
mod.rs1#[cfg(test)]
9mod tests;
10
11use serde::{Deserialize, Serialize};
12
13use crate::ciphertext::Ciphertext;
14use crate::client_key::ClientKey;
15use crate::engine::bootstrapping::CpuBootstrapKey;
16#[cfg(feature = "cuda")]
17use crate::engine::{bootstrapping::CudaBootstrapKey, CudaBooleanEngine};
18use crate::engine::{BinaryGatesEngine, CpuBooleanEngine, WithThreadLocalEngine};
19#[cfg(feature = "cuda")]
20use std::sync::Arc;
21
22pub trait BinaryBooleanGates<L, R> {
23 fn and(&self, ct_left: L, ct_right: R) -> Ciphertext;
24 fn nand(&self, ct_left: L, ct_right: R) -> Ciphertext;
25 fn nor(&self, ct_left: L, ct_right: R) -> Ciphertext;
26 fn or(&self, ct_left: L, ct_right: R) -> Ciphertext;
27 fn xor(&self, ct_left: L, ct_right: R) -> Ciphertext;
28 fn xnor(&self, ct_left: L, ct_right: R) -> Ciphertext;
29}
30
31trait RefFromServerKey {
32 fn get_ref(server_key: &ServerKey) -> &Self;
33}
34
35trait DefaultImplementation {
36 type Engine: WithThreadLocalEngine;
37 type BootsrapKey: RefFromServerKey;
38}
39
40#[derive(Clone)]
41pub struct ServerKey {
42 cpu_key: CpuBootstrapKey,
43 #[cfg(feature = "cuda")]
44 cuda_key: Arc<CudaBootstrapKey>,
45}
46
47#[cfg(not(feature = "cuda"))]
48mod implementation {
49 use super::*;
50
51 impl RefFromServerKey for CpuBootstrapKey {
52 fn get_ref(server_key: &ServerKey) -> &Self {
53 &server_key.cpu_key
54 }
55 }
56
57 impl DefaultImplementation for ServerKey {
58 type Engine = CpuBooleanEngine;
59 type BootsrapKey = CpuBootstrapKey;
60 }
61}
62
63#[cfg(feature = "cuda")]
64mod implementation {
65 use super::*;
66
67 impl RefFromServerKey for CudaBootstrapKey {
68 fn get_ref(server_key: &ServerKey) -> &Self {
69 &server_key.cuda_key
70 }
71 }
72
73 impl DefaultImplementation for ServerKey {
74 type Engine = CudaBooleanEngine;
75 type BootsrapKey = CudaBootstrapKey;
76 }
77}
78
79impl<Lhs, Rhs> BinaryBooleanGates<Lhs, Rhs> for ServerKey
80where
81 <ServerKey as DefaultImplementation>::Engine:
82 BinaryGatesEngine<Lhs, Rhs, <ServerKey as DefaultImplementation>::BootsrapKey>,
83{
84 fn and(&self, ct_left: Lhs, ct_right: Rhs) -> Ciphertext {
85 let bootstrap_key = <ServerKey as DefaultImplementation>::BootsrapKey::get_ref(self);
86 <ServerKey as DefaultImplementation>::Engine::with_thread_local_mut(|engine| {
87 engine.and(ct_left, ct_right, bootstrap_key)
88 })
89 }
90
91 fn nand(&self, ct_left: Lhs, ct_right: Rhs) -> Ciphertext {
92 let bootstrap_key = <ServerKey as DefaultImplementation>::BootsrapKey::get_ref(self);
93 <ServerKey as DefaultImplementation>::Engine::with_thread_local_mut(|engine| {
94 engine.nand(ct_left, ct_right, bootstrap_key)
95 })
96 }
97
98 fn nor(&self, ct_left: Lhs, ct_right: Rhs) -> Ciphertext {
99 let bootstrap_key = <ServerKey as DefaultImplementation>::BootsrapKey::get_ref(self);
100 <ServerKey as DefaultImplementation>::Engine::with_thread_local_mut(|engine| {
101 engine.nor(ct_left, ct_right, bootstrap_key)
102 })
103 }
104
105 fn or(&self, ct_left: Lhs, ct_right: Rhs) -> Ciphertext {
106 let bootstrap_key = <ServerKey as DefaultImplementation>::BootsrapKey::get_ref(self);
107 <ServerKey as DefaultImplementation>::Engine::with_thread_local_mut(|engine| {
108 engine.or(ct_left, ct_right, bootstrap_key)
109 })
110 }
111
112 fn xor(&self, ct_left: Lhs, ct_right: Rhs) -> Ciphertext {
113 let bootstrap_key = <ServerKey as DefaultImplementation>::BootsrapKey::get_ref(self);
114 <ServerKey as DefaultImplementation>::Engine::with_thread_local_mut(|engine| {
115 engine.xor(ct_left, ct_right, bootstrap_key)
116 })
117 }
118
119 fn xnor(&self, ct_left: Lhs, ct_right: Rhs) -> Ciphertext {
120 let bootstrap_key = <ServerKey as DefaultImplementation>::BootsrapKey::get_ref(self);
121 <ServerKey as DefaultImplementation>::Engine::with_thread_local_mut(|engine| {
122 engine.xnor(ct_left, ct_right, bootstrap_key)
123 })
124 }
125}
126
127impl ServerKey {
128 pub fn new(cks: &ClientKey) -> Self {
129 let cpu_key =
130 CpuBooleanEngine::with_thread_local_mut(|engine| engine.create_server_key(cks));
131
132 Self::from(cpu_key)
133 }
134
135 pub fn trivial_encrypt(&self, message: bool) -> Ciphertext {
136 Ciphertext::Trivial(message)
137 }
138
139 pub fn not(&self, ct: &Ciphertext) -> Ciphertext {
140 CpuBooleanEngine::with_thread_local_mut(|engine| engine.not(ct))
141 }
142
143 pub fn mux(
144 &self,
145 ct_condition: &Ciphertext,
146 ct_then: &Ciphertext,
147 ct_else: &Ciphertext,
148 ) -> Ciphertext {
149 #[cfg(feature = "cuda")]
150 {
151 CudaBooleanEngine::with_thread_local_mut(|engine| {
152 engine.mux(ct_condition, ct_then, ct_else, &self.cuda_key)
153 })
154 }
155 #[cfg(not(feature = "cuda"))]
156 {
157 CpuBooleanEngine::with_thread_local_mut(|engine| {
158 engine.mux(ct_condition, ct_then, ct_else, &self.cpu_key)
159 })
160 }
161 }
162}
163
164impl From<CpuBootstrapKey> for ServerKey {
165 fn from(cpu_key: CpuBootstrapKey) -> Self {
166 #[cfg(feature = "cuda")]
167 {
168 let cuda_key = CudaBooleanEngine::with_thread_local_mut(|engine| {
169 engine.create_server_key(&cpu_key)
170 });
171
172 let cuda_key = Arc::new(cuda_key);
173
174 Self { cpu_key, cuda_key }
175 }
176 #[cfg(not(feature = "cuda"))]
177 {
178 Self { cpu_key }
179 }
180 }
181}
182
183impl Serialize for ServerKey {
184 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
185 where
186 S: serde::Serializer,
187 {
188 self.cpu_key.serialize(serializer)
189 }
190}
191
192impl<'de> Deserialize<'de> for ServerKey {
193 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
194 where
195 D: serde::Deserializer<'de>,
196 {
197 let cpu_key = CpuBootstrapKey::deserialize(deserializer)?;
198
199 Ok(Self::from(cpu_key))
200 }
201}