p_ot.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. //! Implementation of the 3-OT protocol.
  2. //!
  3. //! 3-OT is a variant of random oblivious transfer for three parties K, C, and R. K samples a PRF
  4. //! key that defines a pseudorandom vector. Then C can repeatedly choose an index in this vector,
  5. //! and R receives the vector entry at that index without learning anything about the index or the
  6. //! other entries in the vector.
  7. use crate::common::Error;
  8. use communicator::{AbstractCommunicator, Fut, Serializable};
  9. use core::marker::PhantomData;
  10. use ff::Field;
  11. use rayon::prelude::*;
  12. use utils::field::FromPrf;
  13. use utils::permutation::Permutation;
  14. /// Party that holds the PRF key.
  15. pub struct POTKeyParty<F: FromPrf, Perm> {
  16. /// log of the database size
  17. domain_size: usize,
  18. /// if init was run
  19. is_initialized: bool,
  20. /// PRF key of the Index Party
  21. prf_key_i: Option<<F as FromPrf>::PrfKey>,
  22. /// PRF key of the Receiver Party
  23. prf_key_r: Option<<F as FromPrf>::PrfKey>,
  24. /// Permutation
  25. permutation: Option<Perm>,
  26. _phantom: PhantomData<F>,
  27. }
  28. impl<F, Perm> POTKeyParty<F, Perm>
  29. where
  30. F: Field + FromPrf,
  31. F::PrfKey: Sync,
  32. Perm: Permutation + Sync,
  33. {
  34. /// Create a new instance.
  35. pub fn new(domain_size: usize) -> Self {
  36. Self {
  37. domain_size,
  38. is_initialized: false,
  39. prf_key_i: None,
  40. prf_key_r: None,
  41. permutation: None,
  42. _phantom: PhantomData,
  43. }
  44. }
  45. /// Test if the party has been initialized.
  46. pub fn is_initialized(&self) -> bool {
  47. self.is_initialized
  48. }
  49. /// Reset the instance to be used again.
  50. pub fn reset(&mut self) {
  51. *self = Self::new(self.domain_size);
  52. }
  53. /// Steps of the initialization protocol without communication.
  54. pub fn init(&mut self) -> ((F::PrfKey, Perm::Key), F::PrfKey) {
  55. assert!(!self.is_initialized);
  56. self.prf_key_i = Some(F::prf_key_gen());
  57. self.prf_key_r = Some(F::prf_key_gen());
  58. let permutation_key = Perm::sample(self.domain_size);
  59. self.permutation = Some(Perm::from_key(permutation_key));
  60. self.is_initialized = true;
  61. (
  62. (self.prf_key_i.unwrap(), permutation_key),
  63. self.prf_key_r.unwrap(),
  64. )
  65. }
  66. /// Run the initialization protocol.
  67. pub fn run_init<C: AbstractCommunicator>(&mut self, comm: &mut C) -> Result<(), Error>
  68. where
  69. <F as FromPrf>::PrfKey: Serializable,
  70. Perm::Key: Serializable,
  71. {
  72. let (msg_to_index_party, msg_to_receiver_party) = self.init();
  73. comm.send_next(msg_to_index_party)?;
  74. comm.send_previous(msg_to_receiver_party)?;
  75. Ok(())
  76. }
  77. /// Expand the PRF key into a pseudorandom vector.
  78. pub fn expand(&self) -> Vec<F> {
  79. assert!(self.is_initialized);
  80. (0..self.domain_size)
  81. .into_par_iter()
  82. .map(|x| {
  83. let pi_x = self.permutation.as_ref().unwrap().permute(x);
  84. F::prf(&self.prf_key_i.unwrap(), pi_x as u64)
  85. + F::prf(&self.prf_key_r.unwrap(), pi_x as u64)
  86. })
  87. .collect()
  88. }
  89. }
  90. /// Party that chooses the index.
  91. pub struct POTIndexParty<F: FromPrf, Perm> {
  92. /// log of the database size
  93. domain_size: usize,
  94. /// if init was run
  95. is_initialized: bool,
  96. /// PRF key of the Index Party
  97. prf_key_i: Option<<F as FromPrf>::PrfKey>,
  98. /// Permutation
  99. permutation: Option<Perm>,
  100. _phantom: PhantomData<F>,
  101. }
  102. impl<F: Field + FromPrf, Perm: Permutation> POTIndexParty<F, Perm> {
  103. /// Create a new instance.
  104. pub fn new(domain_size: usize) -> Self {
  105. Self {
  106. domain_size,
  107. is_initialized: false,
  108. prf_key_i: None,
  109. permutation: None,
  110. _phantom: PhantomData,
  111. }
  112. }
  113. /// Test if the party has been initialized.
  114. pub fn is_initialized(&self) -> bool {
  115. self.is_initialized
  116. }
  117. /// Reset the instance to be used again.
  118. pub fn reset(&mut self) {
  119. *self = Self::new(self.domain_size);
  120. }
  121. /// Steps of the initialization protocol without communication.
  122. pub fn init(&mut self, prf_key_i: F::PrfKey, permutation_key: Perm::Key) {
  123. assert!(!self.is_initialized);
  124. self.prf_key_i = Some(prf_key_i);
  125. self.permutation = Some(Perm::from_key(permutation_key));
  126. self.is_initialized = true;
  127. }
  128. /// Run the initialization protocol.
  129. pub fn run_init<C: AbstractCommunicator>(&mut self, comm: &mut C) -> Result<(), Error>
  130. where
  131. <F as FromPrf>::PrfKey: Serializable,
  132. Perm::Key: Serializable,
  133. {
  134. let msg_from_key_party: (F::PrfKey, Perm::Key) = comm.receive_previous()?.get()?;
  135. self.init(msg_from_key_party.0, msg_from_key_party.1);
  136. Ok(())
  137. }
  138. /// Steps of the access protocol without communication.
  139. pub fn access(&self, index: usize) -> (usize, F) {
  140. assert!(index < self.domain_size);
  141. let pi_x = self.permutation.as_ref().unwrap().permute(index);
  142. (pi_x, F::prf(&self.prf_key_i.unwrap(), pi_x as u64))
  143. }
  144. /// Run the access protocol.
  145. pub fn run_access<C: AbstractCommunicator>(
  146. &self,
  147. comm: &mut C,
  148. index: usize,
  149. ) -> Result<(), Error>
  150. where
  151. F: Serializable,
  152. {
  153. let msg_to_receiver_party = self.access(index);
  154. comm.send_next(msg_to_receiver_party)?;
  155. Ok(())
  156. }
  157. }
  158. /// Party that receives the output.
  159. pub struct POTReceiverParty<F: FromPrf> {
  160. /// log of the database size
  161. domain_size: usize,
  162. /// if init was run
  163. is_initialized: bool,
  164. /// PRF key of the Receiver Party
  165. prf_key_r: Option<<F as FromPrf>::PrfKey>,
  166. _phantom: PhantomData<F>,
  167. }
  168. impl<F: Field + FromPrf> POTReceiverParty<F> {
  169. /// Create a new instance.
  170. pub fn new(domain_size: usize) -> Self {
  171. Self {
  172. domain_size,
  173. is_initialized: false,
  174. prf_key_r: None,
  175. _phantom: PhantomData,
  176. }
  177. }
  178. /// Test if the party has been initialized.
  179. pub fn is_initialized(&self) -> bool {
  180. self.is_initialized
  181. }
  182. /// Reset the instance to be used again.
  183. pub fn reset(&mut self) {
  184. *self = Self::new(self.domain_size);
  185. }
  186. /// Steps of the initialization protocol without communication.
  187. pub fn init(&mut self, prf_key_r: F::PrfKey) {
  188. assert!(!self.is_initialized);
  189. self.prf_key_r = Some(prf_key_r);
  190. self.is_initialized = true;
  191. }
  192. /// Run the initialization protocol.
  193. pub fn run_init<C: AbstractCommunicator>(&mut self, comm: &mut C) -> Result<(), Error>
  194. where
  195. <F as FromPrf>::PrfKey: Serializable,
  196. {
  197. let msg_from_key_party: F::PrfKey = comm.receive_next()?.get()?;
  198. self.init(msg_from_key_party);
  199. Ok(())
  200. }
  201. /// Steps of the access protocol without communication.
  202. pub fn access(&self, permuted_index: usize, output_share: F) -> F {
  203. assert!(permuted_index < self.domain_size);
  204. F::prf(&self.prf_key_r.unwrap(), permuted_index as u64) + output_share
  205. }
  206. /// Run the access protocol.
  207. pub fn run_access<C: AbstractCommunicator>(&self, comm: &mut C) -> Result<F, Error>
  208. where
  209. F: Serializable,
  210. {
  211. let msg_from_index_party: (usize, F) = comm.receive_previous()?.get()?;
  212. let output = self.access(msg_from_index_party.0, msg_from_index_party.1);
  213. Ok(output)
  214. }
  215. }
  216. /// Combination of three 3-OT instances, where each party takes each role once.
  217. pub struct JointPOTParties<F: FromPrf, Perm> {
  218. key_party: POTKeyParty<F, Perm>,
  219. index_party: POTIndexParty<F, Perm>,
  220. receiver_party: POTReceiverParty<F>,
  221. }
  222. impl<F, Perm> JointPOTParties<F, Perm>
  223. where
  224. F: Field + FromPrf,
  225. F::PrfKey: Sync,
  226. Perm: Permutation + Sync,
  227. {
  228. /// Create a new instance.
  229. pub fn new(domain_size: usize) -> Self {
  230. Self {
  231. key_party: POTKeyParty::new(domain_size),
  232. index_party: POTIndexParty::new(domain_size),
  233. receiver_party: POTReceiverParty::new(domain_size),
  234. }
  235. }
  236. /// Reset this instance.
  237. pub fn reset(&mut self) {
  238. *self = Self::new(self.key_party.domain_size);
  239. }
  240. /// Run the inititialization for all three 3-OT instances.
  241. pub fn init<C: AbstractCommunicator>(&mut self, comm: &mut C) -> Result<(), Error>
  242. where
  243. <F as FromPrf>::PrfKey: Serializable,
  244. Perm::Key: Serializable,
  245. {
  246. self.key_party.run_init(comm)?;
  247. self.index_party.run_init(comm)?;
  248. self.receiver_party.run_init(comm)
  249. }
  250. /// Run the access protocol for the 3-OT instances where the this party chooses the index or
  251. /// receives the output.
  252. pub fn access<C: AbstractCommunicator>(&self, comm: &mut C, my_index: usize) -> Result<F, Error>
  253. where
  254. F: Serializable,
  255. {
  256. self.index_party.run_access(comm, my_index)?;
  257. self.receiver_party.run_access(comm)
  258. }
  259. /// Expands the PRF key for the instances where this party holds the key.
  260. pub fn expand(&self) -> Vec<F> {
  261. self.key_party.expand()
  262. }
  263. }
  264. #[cfg(test)]
  265. mod tests {
  266. use super::*;
  267. use utils::field::Fp;
  268. use utils::permutation::FisherYatesPermutation;
  269. fn test_pot<F, Perm>(log_domain_size: u32)
  270. where
  271. F: Field + FromPrf,
  272. F::PrfKey: Sync,
  273. Perm: Permutation + Sync,
  274. {
  275. let domain_size = 1 << log_domain_size;
  276. // creation
  277. let mut key_party = POTKeyParty::<F, Perm>::new(domain_size);
  278. let mut index_party = POTIndexParty::<F, Perm>::new(domain_size);
  279. let mut receiver_party = POTReceiverParty::<F>::new(domain_size);
  280. assert!(!key_party.is_initialized());
  281. assert!(!index_party.is_initialized());
  282. assert!(!receiver_party.is_initialized());
  283. // init
  284. let (msg_to_index_party, msg_to_receiver_party) = key_party.init();
  285. index_party.init(msg_to_index_party.0, msg_to_index_party.1);
  286. receiver_party.init(msg_to_receiver_party);
  287. assert!(key_party.is_initialized());
  288. assert!(index_party.is_initialized());
  289. assert!(receiver_party.is_initialized());
  290. // expand to the key party's output
  291. let output_k = key_party.expand();
  292. assert_eq!(output_k.len(), domain_size);
  293. // access each index and verify consistency with key party's output
  294. for i in 0..domain_size {
  295. let msg_to_receiver_party = index_party.access(i);
  296. let output = receiver_party.access(msg_to_receiver_party.0, msg_to_receiver_party.1);
  297. assert_eq!(output, output_k[i]);
  298. }
  299. }
  300. #[test]
  301. fn test_all_pot() {
  302. let log_domain_size = 10;
  303. test_pot::<Fp, FisherYatesPermutation>(log_domain_size);
  304. }
  305. }