1use hacspec_lib::Randomness;
5use hmac::{hkdf_expand, hkdf_extract};
6
7use crate::{
8 circuit::Circuit,
9 messages::{Message, MessagePayload, SubMessage},
10 primitives::{
11 auth_share::{AuthBit, Bit, BitID, BitKey},
12 commitment::{Commitment, Opening},
13 mac::{
14 generate_mac_key, hash_to_mac_width, mac, verify_mac, xor_mac_width, Mac, MacKey,
15 MAC_LENGTH,
16 },
17 },
18 utils::ith_bit,
19 Error, COMPUTATIONAL_SECURITY, STATISTICAL_SECURITY,
20};
21
22use std::sync::mpsc::{self, Receiver, Sender};
23
24const SEC_MARGIN_BIT_AUTH: usize = 2 * STATISTICAL_SECURITY * 8;
26pub(crate) const SEC_MARGIN_SHARE_AUTH: usize = STATISTICAL_SECURITY * 8;
28
29const EVALUATOR_ID: usize = 0;
30
31pub struct ChannelConfig {
40 pub(crate) listen: Receiver<Message>,
41 pub(crate) evaluator: Sender<Message>,
42 pub(crate) parties: Vec<Sender<Message>>,
43 pub(crate) broadcast: Sender<Message>,
44 pub id: usize,
46}
47
48#[derive(Debug, Clone)]
50pub struct WireLabel([u8; COMPUTATIONAL_SECURITY]);
51
52struct GarbledAnd {
53 sender: usize,
54 gate_index: usize,
55 g0: Vec<u8>,
56 g1: Vec<u8>,
57 g2: Vec<u8>,
58 g3: Vec<u8>,
59}
60
61pub struct Party {
63 bit_counter: usize,
64 id: usize,
66 num_parties: usize,
68 channels: ChannelConfig,
70 global_mac_key: MacKey,
72 entropy: Randomness,
74 abit_pool: Vec<AuthBit>,
76 ashare_pool: Vec<AuthBit>,
78 enable_logging: bool,
80 log_counter: u128,
82 wire_shares: Vec<Option<(AuthBit, Option<WireLabel>)>>,
84}
85
86impl Party {
87 pub fn new(
92 channels: ChannelConfig,
93 circuit: &Circuit,
94 logging: bool,
95 mut entropy: Randomness,
96 ) -> Self {
97 Self {
98 bit_counter: 0,
99 id: channels.id,
100 num_parties: channels.parties.len(),
101 channels,
102 global_mac_key: generate_mac_key(&mut entropy),
103 entropy,
104 abit_pool: Vec::new(),
105 ashare_pool: Vec::new(),
106 log_counter: 0,
107 enable_logging: logging,
108 wire_shares: vec![None; circuit.num_gates()],
109 }
110 }
111
112 fn broadcast(&mut self, value: &[u8]) -> Result<Vec<(usize, Vec<u8>)>, Error> {
138 let domain_separator = format!("Broadcast-{}", self.id);
140 let (commitment, opening) =
141 Commitment::new(value, domain_separator.as_bytes(), &mut self.entropy);
142
143 let mut received_commitments = Vec::new();
144 for _i in 0..self.id {
146 let commitment_msg = self
147 .channels
148 .listen
149 .recv()
150 .expect("all parties should be online");
151 if let MessagePayload::BroadcastCommitment(received_commitment) = commitment_msg.payload
152 {
153 debug_assert_eq!(commitment_msg.to, self.id);
154 received_commitments.push((commitment_msg.from, received_commitment));
155 } else {
156 return Err(Error::UnexpectedMessage(commitment_msg));
157 }
158 }
159
160 for i in 0..self.num_parties {
163 if i == self.id {
164 continue;
165 }
166
167 self.channels.parties[i]
168 .send(Message {
169 from: self.id,
170 to: i,
171 payload: MessagePayload::BroadcastCommitment(commitment.clone()),
172 })
173 .expect("all parties should be online");
174 }
175
176 for _i in self.id + 1..self.num_parties {
178 let commitment_msg = self
179 .channels
180 .listen
181 .recv()
182 .expect("all parties should be online");
183 if let MessagePayload::BroadcastCommitment(received_commitment) = commitment_msg.payload
184 {
185 debug_assert_eq!(commitment_msg.to, self.id);
186 received_commitments.push((commitment_msg.from, received_commitment));
187 } else {
188 return Err(Error::UnexpectedMessage(commitment_msg));
189 }
190 }
191
192 self.sync().expect("synchronization should have succeeded");
193
194 self.channels
196 .broadcast
197 .send(Message {
198 from: self.id,
199 to: self.id,
200 payload: MessagePayload::BroadcastOpening(opening),
201 })
202 .expect("all parties should be online");
203
204 let mut received_values = Vec::new();
206 for _i in 0..self.num_parties - 1 {
207 let opening_msg = self
208 .channels
209 .listen
210 .recv()
211 .expect("all parties should be online");
212 if let MessagePayload::BroadcastOpening(ref received_opening) = opening_msg.payload {
213 let received_commitment = &received_commitments
214 .iter()
215 .find(|(received_from, _)| *received_from == opening_msg.from)
216 .expect("should get opening from all parties")
217 .1;
218 let received_value = received_commitment.open(received_opening)?;
219 received_values.push((opening_msg.from, received_value));
220 } else {
221 return Err(Error::UnexpectedMessage(opening_msg));
222 }
223 }
224
225 self.sync().expect("synchronization should have succeeded");
226 Ok(received_values)
227 }
228
229 fn broadcast_commitments(
231 &mut self,
232 commitment_0: Commitment,
233 commitment_1: Commitment,
234 commitment_macs: Commitment,
235 ) -> Result<Vec<(usize, Commitment, Commitment, Commitment)>, Error> {
236 let mut commitment_bytes = Vec::new();
237 commitment_bytes.extend_from_slice(&commitment_0.as_bytes());
238 commitment_bytes.extend_from_slice(&commitment_1.as_bytes());
239 commitment_bytes.extend_from_slice(&commitment_macs.as_bytes());
240
241 let other_commitment_bytes = self.broadcast(&commitment_bytes)?;
242 let mut results = Vec::new();
243 for j in 0..self.num_parties {
244 if j == self.id {
245 continue;
246 }
247 let (_party, their_commitment_bytes) = other_commitment_bytes
248 .iter()
249 .find(|(party, _)| *party == j)
250 .expect("should have received commitments from every other party");
251 let (their_commitment_0, rest) = Commitment::from_bytes(their_commitment_bytes)?;
252 let (their_commitment_1, rest) = Commitment::from_bytes(&rest)?;
253 let (their_commitment_macs, rest) = Commitment::from_bytes(&rest)?;
254 debug_assert!(rest.is_empty());
255 results.push((
256 j,
257 their_commitment_0,
258 their_commitment_1,
259 their_commitment_macs,
260 ))
261 }
262
263 Ok(results)
264 }
265
266 fn broadcast_opening(&mut self, opening: Opening) -> Result<Vec<(usize, Opening)>, Error> {
268 let other_opening_bytes = self.broadcast(&opening.as_bytes())?;
269 let mut results = Vec::new();
270 for j in 0..self.num_parties {
271 if j == self.id {
272 continue;
273 }
274 let (_party, their_opening_bytes) = other_opening_bytes
275 .iter()
276 .find(|(party, _)| *party == j)
277 .expect("should have received openings from all other parties");
278 results.push((j, Opening::from_bytes(their_opening_bytes)?));
279 }
280 Ok(results)
281 }
282
283 fn is_evaluator(&self) -> bool {
285 self.id == EVALUATOR_ID
286 }
287
288 fn precompute_abits(&mut self, len: usize) -> Result<Vec<AuthBit>, Error> {
297 let len_unchecked = len + SEC_MARGIN_BIT_AUTH;
298
299 let random_bytes = self
301 .entropy
302 .bytes(len_unchecked / 8 + 1)
303 .expect("sufficient randomness should have been provided externally")
304 .to_owned();
305 let mut bits = Vec::new();
306
307 for i in 0..len_unchecked {
308 bits.push(Bit {
309 id: self.fresh_bit_id(),
310 value: ith_bit(i, &random_bytes),
311 })
312 }
313
314 let mut authenticated_bits = Vec::new();
317 for (_bit_index, bit) in bits.into_iter().enumerate() {
318 let mut computed_keys: Vec<BitKey> = Vec::new();
319 let mut received_macs = Vec::new();
320
321 for bit_holder in 0..self.id {
323 let computed_key = self.provide_bit_authentication(bit_holder)?;
324 computed_keys.push(computed_key)
325 }
326
327 for authenticator in 0..self.num_parties {
329 if authenticator == self.id {
330 continue;
331 }
332
333 let received_mac: Mac = self.obtain_bit_authentication(authenticator, &bit)?;
334 received_macs.push((authenticator, received_mac));
335 }
336
337 for bit_holder in self.id + 1..self.num_parties {
339 let computed_key = self.provide_bit_authentication(bit_holder)?;
340 computed_keys.push(computed_key)
341 }
342
343 self.sync().expect("synchronization should have succeeded");
344
345 authenticated_bits.push(AuthBit {
346 bit,
347 macs: received_macs,
348 mac_keys: computed_keys,
349 })
350 }
351
352 self.sync().expect("synchronization should have succeeded");
353
354 self.bit_auth_check(&authenticated_bits)
358 .expect("bit authentication check must not fail");
359
360 Ok(authenticated_bits[0..len].to_vec())
362 }
363
364 fn random_authenticated_shares(&mut self, len: usize) -> Result<Vec<AuthBit>, Error> {
366 let len_unchecked = len + SEC_MARGIN_SHARE_AUTH;
367 let authenticated_bits: Vec<AuthBit> = self.abit_pool.drain(..len_unchecked).collect();
368
369 for r in len..len + SEC_MARGIN_SHARE_AUTH {
371 let domain_separator_0 = format!("Share authentication {} - 0", self.id);
372 let domain_separator_1 = format!("Share authentication {} - 1", self.id);
373 let domain_separator_macs = format!("Share authentication {} - macs", self.id);
374
375 let mut mac_0 = [0u8; MAC_LENGTH]; for key in authenticated_bits[r].mac_keys.iter() {
377 for byte in 0..mac_0.len() {
378 mac_0[byte] ^= key.mac_key[byte];
379 }
380 }
381
382 let mut mac_1 = [0u8; MAC_LENGTH]; for key in authenticated_bits[r].mac_keys.iter() {
384 for byte in 0..mac_1.len() {
385 mac_1[byte] ^= key.mac_key[byte] ^ self.global_mac_key[byte];
386 }
387 }
388
389 let all_macs: Vec<u8> = authenticated_bits[r].serialize_bit_macs(); let (com0, op0) =
392 Commitment::new(&mac_0, domain_separator_0.as_bytes(), &mut self.entropy);
393 let (com1, op1) =
394 Commitment::new(&mac_1, domain_separator_1.as_bytes(), &mut self.entropy);
395 let (com_macs, op_macs) = Commitment::new(
396 &all_macs,
397 domain_separator_macs.as_bytes(),
398 &mut self.entropy,
399 );
400
401 let received_commitments = self.broadcast_commitments(com0, com1, com_macs)?;
402
403 let received_mac_openings = self.broadcast_opening(op_macs)?;
404
405 let mut other_bits_macs = Vec::new();
407 for (party, their_opening) in received_mac_openings {
408 let (_, _, _, their_mac_commitment) = received_commitments
409 .iter()
410 .find(|(committing_party, _, _, _)| *committing_party == party)
411 .expect("should have received commitments from all parties");
412 other_bits_macs.push((
413 party,
414 AuthBit::deserialize_bit_macs(&their_mac_commitment.open(&their_opening)?)?,
415 ));
416 }
417
418 debug_assert_eq!(
419 other_bits_macs.len(),
420 self.num_parties - 1,
421 "should have received valid openings from all other parties"
422 );
423
424 let mut xor_macs = vec![[0u8; MAC_LENGTH]; self.num_parties];
426
427 for (maccing_party, xored_mac) in xor_macs.iter_mut().enumerate() {
428 if maccing_party == self.id {
429 continue;
431 }
432
433 for p in 0..self.num_parties {
434 let their_mac = if p == self.id {
435 authenticated_bits[r]
436 .macs
437 .iter()
438 .find(|(party, _mac)| *party == maccing_party)
439 .expect("should have MACs from all other parties")
440 .1
441 } else {
442 let (_sending_party, (_other_bit, other_macs)) = other_bits_macs
443 .iter()
444 .find(|(sending_party, _rest)| *sending_party == p)
445 .expect(
446 "should have gotten bit values and MACs from all other parties",
447 );
448 other_macs[maccing_party]
449 };
450 for byte in 0..MAC_LENGTH {
451 xored_mac[byte] ^= their_mac[byte];
452 }
453 }
454 }
455
456 let mut b_i = false;
457 for (_party, (bit, _macs)) in other_bits_macs.iter() {
459 b_i ^= *bit;
460 }
461
462 let mut xor_bits = vec![authenticated_bits[r].bit.value; self.num_parties];
464 for j in 0..self.num_parties {
465 if j == self.id {
466 xor_bits[j] = b_i;
467 }
468 for (party, (bit, _macs)) in other_bits_macs.iter() {
469 if *party == j {
470 continue;
471 }
472 xor_bits[j] ^= bit;
473 }
474 }
475
476 let received_bit_openings = if b_i {
477 self.broadcast_opening(op1)?
478 } else {
479 self.broadcast_opening(op0)?
480 };
481
482 for (party, bit_opening) in received_bit_openings {
483 let (_, their_com0, their_com1, _) = received_commitments
484 .iter()
485 .find(|(committing_party, _, _, _)| *committing_party == party)
486 .expect("should have received commitments from all other parties");
487 let their_mac = if !xor_bits[party] {
488 their_com0.open(&bit_opening).unwrap()
489 } else {
490 their_com1.open(&bit_opening).unwrap()
491 };
492
493 if their_mac != xor_macs[party] {
494 self.log(&format!(
495 "Error while checking party {}'s bit commitment!",
496 party
497 ));
498 return Err(Error::CheckFailed(
499 "Share Authentication failed".to_string(),
500 ));
501 }
502 }
503 }
504
505 Ok(authenticated_bits[0..len].to_vec())
506 }
507
508 fn half_and(&mut self, x: &AuthBit, y: &AuthBit) -> Result<bool, Error> {
510 fn lsb(input: &[u8]) -> bool {
512 (input[input.len() - 1] & 1) != 0
513 }
514
515 let domain_separator = b"half-and-hash";
516
517 let mut t_js = vec![false; self.num_parties];
518 let mut s_js = vec![false; self.num_parties];
519
520 for _j in 0..self.id {
522 let hashes_message = self.channels.listen.recv().unwrap();
523 if let Message {
524 from,
525 to,
526 payload: MessagePayload::HalfAndHashes(hash_j_0, hash_j_1),
527 } = hashes_message
528 {
529 debug_assert_eq!(to, self.id);
530 let their_mac = x
531 .macs
532 .iter()
533 .find(|(party, _mac)| *party == from)
534 .expect("should have MACs from all other parties")
535 .1;
536 let hash_lsb = lsb(&hash_to_mac_width(domain_separator, &their_mac));
537 let t_j = if x.bit.value {
538 hash_j_1 ^ hash_lsb
539 } else {
540 hash_j_0 ^ hash_lsb
541 };
542 t_js[from] = t_j;
543 } else {
544 return Err(Error::UnexpectedMessage(hashes_message));
545 }
546 }
547
548 for j in 0..self.num_parties {
549 if j == self.id {
550 continue;
551 }
552 let s_j = self
553 .entropy
554 .bit()
555 .expect("sufficient randomness should have been provided externally");
556 s_js[j] = s_j;
557
558 let input_0 = x
560 .mac_keys
561 .iter()
562 .find(|key| key.bit_holder == j)
563 .expect("should have keys for all other parties")
564 .mac_key;
565
566 let mut input_1 = [0u8; MAC_LENGTH];
568 for byte in 0..MAC_LENGTH {
569 input_1[byte] = input_0[byte] ^ self.global_mac_key[byte];
570 }
571
572 let h_0 = lsb(&hash_to_mac_width(domain_separator, &input_0)) ^ s_j;
573 let h_1 = lsb(&hash_to_mac_width(domain_separator, &input_1)) ^ s_j ^ y.bit.value;
574 self.channels.parties[j]
575 .send(Message {
576 from: self.id,
577 to: j,
578 payload: MessagePayload::HalfAndHashes(h_0, h_1),
579 })
580 .unwrap();
581 }
582
583 for _j in self.id + 1..self.num_parties {
585 let hashes_message = self.channels.listen.recv().unwrap();
586 if let Message {
587 from,
588 to,
589 payload: MessagePayload::HalfAndHashes(hash_j_0, hash_j_1),
590 } = hashes_message
591 {
592 debug_assert_eq!(to, self.id);
593 let their_mac = x
594 .macs
595 .iter()
596 .find(|(party, _mac)| *party == from)
597 .expect("should have MACs from all other parties")
598 .1;
599 let hash_lsb = lsb(&hash_to_mac_width(domain_separator, &their_mac));
600 let t_j = if x.bit.value {
601 hash_j_1 ^ hash_lsb
602 } else {
603 hash_j_0 ^ hash_lsb
604 };
605 t_js[from] = t_j;
606 } else {
607 return Err(Error::UnexpectedMessage(hashes_message));
608 }
609 }
610
611 self.sync().expect("sync should always succeed");
612
613 let mut v_i = false;
614 for j in 0..self.num_parties {
615 if j == self.id {
616 continue;
617 }
618 v_i ^= t_js[j] ^ s_js[j];
619 }
620
621 Ok(v_i)
622 }
623
624 fn random_leaky_and(&mut self, len: usize) -> Result<Vec<(AuthBit, AuthBit, AuthBit)>, Error> {
626 let mut results = Vec::new();
627 let mut shares: Vec<AuthBit> = self.ashare_pool.drain(..3 * len).collect();
628 for _i in 0..len {
629 let x = shares.pop().expect("requested enough authenticated bits");
630 let y = shares.pop().expect("requested enough authenticated bits");
631 let mut r = shares.pop().expect("requested enough authenticated bits");
632
633 let v_i = self.half_and(&x, &y)?;
634
635 let z_i_value = (y.bit.value && x.bit.value) ^ v_i;
636 let e_i_value = z_i_value ^ r.bit.value;
637
638 let other_e_is = self.broadcast(&[e_i_value as u8])?;
639 for key in r.mac_keys.iter_mut() {
640 let (_, other_e_j) = other_e_is
641 .iter()
642 .find(|(party, _)| *party == key.bit_holder)
643 .expect("should have received e_j from every other party j");
644 let correction_necessary = other_e_j[0] != 0;
645 if correction_necessary {
646 key.mac_key = xor_mac_width(&key.mac_key, &self.global_mac_key);
647 }
648 }
649 r.bit.value = z_i_value;
650 let z = r;
651
652 self.sync().expect("sync should always succeed");
653
654 let mut phi = [0u8; MAC_LENGTH];
657 for key in y.mac_keys.iter() {
658 let (_, their_mac) = y
659 .macs
660 .iter()
661 .find(|(maccing_party, _)| *maccing_party == key.bit_holder)
662 .unwrap();
663 let intermediate_xor = xor_mac_width(&key.mac_key, their_mac);
664 phi = xor_mac_width(&phi, &intermediate_xor);
665 }
666
667 if y.bit.value {
668 phi = xor_mac_width(&phi, &self.global_mac_key);
669 }
670
671 let mut mac_phis = Vec::new();
673 let mut key_phis = Vec::new();
674 let domain_separator_triple = b"triple-check";
675 for _j in 0..self.id {
676 let u_message = self.channels.listen.recv().unwrap();
677 if let Message {
678 from,
679 to,
680 payload: MessagePayload::LeakyAndU(u),
681 } = u_message
682 {
683 debug_assert_eq!(self.id, to);
684 let (_, their_mac) = x
686 .macs
687 .iter()
688 .find(|(maccing_party, _)| *maccing_party == from)
689 .expect("should have MACs from all other parties");
690 let mut mac_phi = hash_to_mac_width(domain_separator_triple, their_mac);
691 if x.bit.value {
692 for byte in 0..MAC_LENGTH {
693 mac_phi[byte] ^= u[byte];
694 }
695 }
696 mac_phis.push((from, mac_phi));
697 } else {
698 return Err(Error::UnexpectedMessage(u_message));
699 }
700 }
701
702 for j in 0..self.num_parties {
704 if j == self.id {
705 continue;
706 }
707 let my_key = x
709 .mac_keys
710 .iter()
711 .find(|k| k.bit_holder == j)
712 .expect("should have keys for all other parties' bits");
713
714 let k_phi = hash_to_mac_width(domain_separator_triple, &my_key.mac_key);
715 key_phis.push((j, k_phi));
716
717 let u_j_hash = hash_to_mac_width(
719 domain_separator_triple,
720 &xor_mac_width(&my_key.mac_key, &self.global_mac_key),
721 );
722 let u_j = xor_mac_width(&u_j_hash, &k_phi);
723 let u_j = xor_mac_width(&u_j, &phi);
724
725 self.channels.parties[j]
726 .send(Message {
727 from: self.id,
728 to: j,
729 payload: MessagePayload::LeakyAndU(u_j),
730 })
731 .unwrap();
732 }
733
734 for _j in self.id + 1..self.num_parties {
736 let u_message = self.channels.listen.recv().unwrap();
737 if let Message {
738 from,
739 to,
740 payload: MessagePayload::LeakyAndU(u),
741 } = u_message
742 {
743 debug_assert_eq!(self.id, to);
744 let (_, their_mac) = x
746 .macs
747 .iter()
748 .find(|(maccing_party, _)| *maccing_party == from)
749 .expect("should have MACs from all other parties");
750 let mut mac_phi = hash_to_mac_width(domain_separator_triple, their_mac);
751 if x.bit.value {
752 for byte in 0..MAC_LENGTH {
753 mac_phi[byte] ^= u[byte];
754 }
755 }
756 mac_phis.push((from, mac_phi));
757 } else {
758 return Err(Error::UnexpectedMessage(u_message));
759 }
760 }
761
762 self.sync().expect("sync should always succeed");
763
764 let mut h = [0u8; MAC_LENGTH];
766
767 for (j, key_phi) in key_phis {
768 let (_, mac_phi) = mac_phis
769 .iter()
770 .find(|(maccing_party, _)| *maccing_party == j)
771 .expect("should have a MAC from every other party");
772 let intermediate_xor = xor_mac_width(&key_phi, mac_phi);
773 h = xor_mac_width(&h, &intermediate_xor);
774 }
775
776 for key in z.mac_keys.iter() {
777 let (_, their_mac) = z
778 .macs
779 .iter()
780 .find(|(maccing_party, _)| key.bit_holder == *maccing_party)
781 .expect("should have MACs from all other parties");
782 let intermediate_xor = xor_mac_width(&key.mac_key, their_mac);
783 h = xor_mac_width(&h, &intermediate_xor);
784 }
785
786 if x.bit.value {
787 h = xor_mac_width(&h, &phi);
788 }
789 if z.bit.value {
790 h = xor_mac_width(&h, &self.global_mac_key);
791 }
792
793 let other_hs = self.broadcast(&h)?;
795
796 let mut test = h;
798 for (_, other_h) in other_hs {
799 test = xor_mac_width(
800 &test,
801 &other_h
802 .try_into()
803 .expect("should have received the right number of bytes"),
804 );
805 }
806
807 if test != [0u8; MAC_LENGTH] {
808 return Err(Error::CheckFailed("Leaky AND xor check failed".to_string()));
809 }
810
811 results.push((x, y, z));
812 }
813
814 Ok(results)
815 }
816
817 fn open_bit(&mut self, bit: &AuthBit) -> Result<bool, Error> {
819 let mut other_bits = Vec::new();
820
821 for _j in 0..self.id {
823 let reveal_message = self.channels.listen.recv().unwrap();
824 if let Message {
825 from,
826 to,
827 payload: MessagePayload::BitReveal(value, mac),
828 } = reveal_message
829 {
830 debug_assert_eq!(self.id, to);
831 let my_key = bit
832 .mac_keys
833 .iter()
834 .find(|k| k.bit_holder == from)
835 .expect("should have a key for every other party");
836 if !verify_mac(&value, &mac, &my_key.mac_key, &self.global_mac_key) {
837 return Err(Error::CheckFailed("Bit reveal failed".to_string()));
838 }
839 other_bits.push((from, value));
840 } else {
841 return Err(Error::UnexpectedMessage(reveal_message));
842 }
843 }
844
845 for j in 0..self.num_parties {
847 if j == self.id {
848 continue;
849 }
850 let (_, their_mac) = bit
851 .macs
852 .iter()
853 .find(|(maccing_party, _mac)| j == *maccing_party)
854 .expect("should have MACs from all other parties");
855 self.channels.parties[j]
856 .send(Message {
857 from: self.id,
858 to: j,
859 payload: MessagePayload::BitReveal(bit.bit.value, *their_mac),
860 })
861 .unwrap();
862 }
863
864 for _j in self.id + 1..self.num_parties {
866 let reveal_message = self.channels.listen.recv().unwrap();
867 if let Message {
868 from,
869 to,
870 payload: MessagePayload::BitReveal(value, mac),
871 } = reveal_message
872 {
873 debug_assert_eq!(self.id, to);
874 let my_key = bit
875 .mac_keys
876 .iter()
877 .find(|k| k.bit_holder == from)
878 .expect("should have a key for every other party");
879 if !verify_mac(&value, &mac, &my_key.mac_key, &self.global_mac_key) {
880 return Err(Error::CheckFailed("Bit reveal failed".to_string()));
881 }
882 other_bits.push((from, value));
883 } else {
884 return Err(Error::UnexpectedMessage(reveal_message));
885 }
886 }
887
888 let mut result = bit.bit.value;
889 for (_, other_bit) in other_bits {
890 result ^= other_bit
891 }
892
893 self.sync().expect("sync should always succeed");
894
895 Ok(result)
896 }
897
898 fn xor_abits(&mut self, a: &AuthBit, b: &AuthBit) -> AuthBit {
901 let mut macs = Vec::new();
902 for (maccing_party, mac) in a.macs.iter() {
903 let mut xored_mac = [0u8; MAC_LENGTH];
904 let other_mac = b
905 .macs
906 .iter()
907 .find(|(party, _)| *party == *maccing_party)
908 .expect("should have MACs from all other parties")
909 .1;
910 for byte in 0..MAC_LENGTH {
911 xored_mac[byte] = mac[byte] ^ other_mac[byte];
912 }
913 macs.push((*maccing_party, xored_mac))
914 }
915
916 let mut mac_keys = Vec::new();
917 for key in a.mac_keys.iter() {
918 let mut xored_key = [0u8; MAC_LENGTH];
919 let other_key = b
920 .mac_keys
921 .iter()
922 .find(|other_key| key.bit_holder == other_key.bit_holder)
923 .expect("should have two MAC keys for every other party")
924 .mac_key;
925 for byte in 0..MAC_LENGTH {
926 xored_key[byte] = key.mac_key[byte] ^ other_key[byte];
927 }
928 mac_keys.push(BitKey {
929 holder_bit_id: BitID(0), bit_holder: key.bit_holder,
931 mac_key: xored_key,
932 })
933 }
934
935 AuthBit {
936 bit: Bit {
937 id: self.fresh_bit_id(),
938 value: a.bit.value ^ b.bit.value,
939 },
940 macs,
941 mac_keys,
942 }
943 }
944
945 fn and_abits(
946 &mut self,
947 random_triple: (AuthBit, AuthBit, AuthBit),
948 x: &AuthBit,
949 y: &AuthBit,
950 ) -> Result<AuthBit, Error> {
951 let (a, b, c) = random_triple;
952 let blinded_x_share = self.xor_abits(x, &a);
953 let blinded_y_share = self.xor_abits(y, &b);
954
955 let blinded_x = self.open_bit(&blinded_x_share)?;
956 let blinded_y = self.open_bit(&blinded_y_share)?;
957
958 let mut result = c;
959 if blinded_x {
960 result = self.xor_abits(&result, &y);
961 }
962 if !blinded_y {
963 result = self.xor_abits(&result, &a);
964 }
965
966 Ok(result)
967 }
968
969 fn invert_abit(&mut self, a: &AuthBit) -> AuthBit {
972 let mut mac_keys = a.mac_keys.clone();
973 for key in mac_keys.iter_mut() {
974 key.mac_key = xor_mac_width(&key.mac_key, &self.global_mac_key)
975 }
976
977 AuthBit {
978 bit: Bit {
979 id: self.fresh_bit_id(),
980 value: a.bit.value ^ true,
981 },
982 macs: a.macs.clone(),
983 mac_keys,
984 }
985 }
986
987 fn random_and_shares(
989 &mut self,
990 len: usize,
991 bucket_size: usize,
992 ) -> Result<Vec<(AuthBit, AuthBit, AuthBit)>, Error> {
993 let leaky_ands = self.random_leaky_and(len * bucket_size)?;
995
996 let random_indices = self.coin_flip(leaky_ands.len() * 8 * 16)?;
1000 let mut indexed_ands: Vec<(u128, (AuthBit, AuthBit, AuthBit))> = random_indices
1001 .chunks_exact(16)
1002 .map(|chunk| {
1003 u128::from_be_bytes(chunk.try_into().expect("chunks are exactly the right size"))
1004 })
1005 .zip(leaky_ands)
1006 .collect();
1007 indexed_ands.sort_by_key(|(index, _)| *index);
1008 let leaky_ands: Vec<&(AuthBit, AuthBit, AuthBit)> =
1009 indexed_ands.iter().map(|(_, triple)| triple).collect();
1010
1011 let mut results = Vec::new();
1013 for bucket in leaky_ands.chunks_exact(bucket_size) {
1014 let (mut x, y, mut z) = bucket[0].clone();
1015
1016 for (next_x, next_y, next_z) in bucket[1..].iter() {
1017 let d_i = self.xor_abits(&y, next_y);
1018 let d = self.open_bit(&d_i)?;
1019
1020 x = self.xor_abits(&x, next_x);
1021 z = self.xor_abits(&z, next_z);
1022 if d {
1023 z = self.xor_abits(&z, next_x);
1024 }
1025 }
1026 results.push((x, y, z));
1027 }
1028
1029 Ok(results)
1030 }
1031
1032 fn bit_auth_check(&mut self, auth_bits: &[AuthBit]) -> Result<(), Error> {
1034 for _j in 0..SEC_MARGIN_BIT_AUTH {
1035 let r = self.coin_flip(auth_bits.len())?;
1037
1038 let mut x_j = false;
1040 for (m, xm) in auth_bits.iter().enumerate() {
1041 x_j ^= ith_bit(m, &r) & xm.bit.value;
1042 }
1043
1044 let other_x_j_bytes = self.broadcast(&[x_j as u8])?;
1046
1047 let mut other_x_js = Vec::new();
1048 for (party, other_x_j) in other_x_j_bytes {
1049 debug_assert!(other_x_j.len() == 1);
1050 other_x_js.push((party, other_x_j[0] != 0))
1051 }
1052
1053 self.sync().expect("synchronization should have succeeded");
1054
1055 let mut xored_keys = vec![[0u8; MAC_LENGTH]; self.num_parties];
1057 let mut xored_tags = vec![[0u8; MAC_LENGTH]; self.num_parties];
1058 for (m, xm) in auth_bits.iter().enumerate() {
1059 if ith_bit(m, &r) {
1060 for mac_keys in xm.mac_keys.iter() {
1061 for byte in 0..mac_keys.mac_key.len() {
1062 xored_keys[mac_keys.bit_holder][byte] ^= mac_keys.mac_key[byte];
1063 }
1064 }
1065 for (key_holder, tag) in xm.macs.iter() {
1066 for (index, tag_byte) in tag.iter().enumerate() {
1067 xored_tags[*key_holder][index] ^= *tag_byte;
1068 }
1069 }
1070 }
1071 }
1072
1073 let mut received_macs = Vec::new();
1075 for _i in 0..self.id {
1076 let mac_message = self
1077 .channels
1078 .listen
1079 .recv()
1080 .expect("all parties should be online");
1081 if let MessagePayload::Mac(mac) = mac_message.payload {
1082 debug_assert_eq!(mac_message.to, self.id, "Wrong recipient for MAC message");
1083 received_macs.push((mac_message.from, mac));
1084 } else {
1085 return Err(Error::UnexpectedMessage(mac_message));
1086 }
1087 }
1088
1089 for i in 0..self.num_parties {
1090 if i == self.id {
1091 continue;
1092 }
1093
1094 let tag = xored_tags[i];
1095
1096 let mac_message = Message {
1097 from: self.id,
1098 to: i,
1099 payload: MessagePayload::Mac(tag),
1100 };
1101 self.channels.parties[i]
1102 .send(mac_message)
1103 .expect("all parties should be online");
1104 }
1105
1106 for _i in self.id + 1..self.num_parties {
1107 let mac_message = self
1108 .channels
1109 .listen
1110 .recv()
1111 .expect("all parties should be online");
1112 if let MessagePayload::Mac(mac) = mac_message.payload {
1113 debug_assert_eq!(mac_message.to, self.id, "Wrong recipient for MAC message");
1114 received_macs.push((mac_message.from, mac));
1115 } else {
1116 return Err(Error::UnexpectedMessage(mac_message));
1117 }
1118 }
1119
1120 self.sync().expect("synchronization should have succeeded");
1121
1122 for (party, mac) in received_macs {
1124 let other_xj = other_x_js
1125 .iter()
1126 .find(|(xj_party, _)| *xj_party == party)
1127 .expect("should have an xj from every other party")
1128 .1;
1129 let key = xored_keys[party];
1130
1131 if !verify_mac(&other_xj, &mac, &key, &self.global_mac_key) {
1132 panic!("Party {}: {}'s MAC verification failed: {other_xj}\nMAC: {mac:?}\nLocal key: {key:?}\nGlobal key: {:?}\n", self.id, party, self.global_mac_key);
1133 }
1134 }
1135 }
1136 Ok(())
1137 }
1138
1139 fn coin_flip(&mut self, len: usize) -> Result<Vec<u8>, Error> {
1142 let my_contribution = self
1143 .entropy
1144 .bytes(len / 8 + 1)
1145 .expect("sufficient randomness should have been provided externally")
1146 .to_owned();
1147 let other_contributions = self.broadcast(&my_contribution)?;
1148
1149 let mut result = my_contribution;
1150 for (_party, their_contribution) in other_contributions {
1151 debug_assert_eq!(
1152 their_contribution.len(),
1153 result.len(),
1154 "all randomness contributions must be of the same length"
1155 );
1156 for i in 0..result.len() {
1157 result[i] ^= their_contribution[i]
1158 }
1159 }
1160
1161 Ok(result)
1162 }
1163
1164 fn ot_send(
1169 &mut self,
1170 receiver_address: Sender<SubMessage>,
1171 my_inbox: Receiver<SubMessage>,
1172 receiver_id: usize,
1173 left_input: &[u8],
1174 right_input: &[u8],
1175 ) -> Result<(), Error> {
1176 let domain_separator = format!("OT-{}-{}", self.id, receiver_id);
1177 let (sender_state, sender_commitment) =
1178 crate::primitives::ot::OTSender::init(&mut self.entropy, domain_separator.as_bytes())?;
1179 receiver_address
1180 .send(SubMessage::OTCommit(sender_commitment))
1181 .expect("all parties should be online");
1182
1183 let selection_msg = my_inbox.recv().expect("all parties should be online");
1184 if let SubMessage::OTSelect(selection) = selection_msg {
1185 let payload =
1186 sender_state.send(left_input, right_input, &selection, &mut self.entropy)?;
1187
1188 receiver_address
1189 .send(SubMessage::OTSend(payload))
1190 .expect("all parties should be online");
1191 Ok(())
1192 } else {
1193 Err(Error::UnexpectedSubprotocolMessage(selection_msg))
1194 }
1195 }
1196
1197 fn ot_receive(
1202 &mut self,
1203 choose_left_input: bool,
1204 sender_address: Sender<SubMessage>,
1205 my_inbox: Receiver<SubMessage>,
1206 sender_id: usize,
1207 ) -> Result<Vec<u8>, Error> {
1208 let ot_commit_msg = my_inbox.recv().expect("all parties should be online");
1209 if let SubMessage::OTCommit(commitment) = ot_commit_msg {
1210 let domain_separator = format!("OT-{}-{}", sender_id, self.id);
1211 let (receiver_state, receiver_selection) = crate::primitives::ot::OTReceiver::select(
1212 &mut self.entropy,
1213 domain_separator.as_bytes(),
1214 commitment,
1215 choose_left_input,
1216 )?;
1217 sender_address
1218 .send(SubMessage::OTSelect(receiver_selection))
1219 .expect("all parties should be online");
1220 let payload_msg = my_inbox.recv().expect("all parties should be online");
1221 if let SubMessage::OTSend(payload) = payload_msg {
1222 let result = receiver_state.receive(payload)?;
1223 Ok(result)
1224 } else {
1225 Err(Error::UnexpectedSubprotocolMessage(payload_msg))
1226 }
1227 } else {
1228 Err(Error::UnexpectedSubprotocolMessage(ot_commit_msg))
1229 }
1230 }
1231
1232 fn fresh_bit_id(&mut self) -> BitID {
1234 let res = self.bit_counter;
1235 self.bit_counter += 1;
1236 BitID(res)
1237 }
1238
1239 fn obtain_bit_authentication(
1249 &mut self,
1250 authenticator: usize,
1251 local_bit: &Bit,
1252 ) -> Result<Mac, Error> {
1253 let (my_address, my_inbox) = mpsc::channel::<SubMessage>();
1255 let (their_address, their_inbox) = mpsc::channel::<SubMessage>();
1256
1257 self.channels.parties[authenticator]
1260 .send(Message {
1261 from: self.id,
1262 to: authenticator,
1263 payload: MessagePayload::RequestBitAuth(
1264 local_bit.id.clone(),
1265 my_address,
1266 their_inbox,
1267 ),
1268 })
1269 .expect("all parties should be online");
1270
1271 let received_mac: Mac = self
1274 .ot_receive(local_bit.value, their_address, my_inbox, authenticator)?
1275 .try_into()
1276 .expect("should receive a MAC of the right length");
1277
1278 Ok(received_mac)
1279 }
1280
1281 fn provide_bit_authentication(&mut self, bit_holder: usize) -> Result<BitKey, Error> {
1292 let request_msg = self
1293 .channels
1294 .listen
1295 .recv()
1296 .expect("all parties should be online");
1297
1298 if let Message {
1299 to,
1300 from,
1301 payload: MessagePayload::RequestBitAuth(holder_bit_id, their_address, my_inbox),
1302 } = request_msg
1303 {
1304 debug_assert_eq!(to, self.id, "Got a wrongly addressed message");
1305
1306 let (mac_on_true, mac_on_false) = mac(&true, &self.global_mac_key, &mut self.entropy);
1309
1310 self.ot_send(their_address, my_inbox, from, &mac_on_true, &mac_on_false)?;
1313
1314 Ok(BitKey {
1315 holder_bit_id,
1316 bit_holder,
1317 mac_key: mac_on_false,
1318 })
1319 } else {
1320 self.log(&format!("Bit Auth: Unexpected message {request_msg:?}"));
1321 Err(Error::UnexpectedMessage(request_msg))
1322 }
1323 }
1324
1325 fn function_independent(&mut self, circuit: &Circuit) -> Result<(), Error> {
1329 self.ashare_pool = self.random_authenticated_shares(circuit.share_authentication_cost())?;
1330
1331 for (gate_index, gate) in circuit.gates.iter().enumerate() {
1332 match *gate {
1333 crate::circuit::WiredGate::Input(_) | crate::circuit::WiredGate::And(_, _) => {
1334 let share = self
1335 .ashare_pool
1336 .pop()
1337 .expect("should have pre-computed enough authenticated random shares");
1338 let label = self
1339 .entropy
1340 .bytes(COMPUTATIONAL_SECURITY)
1341 .expect("should have provided enough randoness externally")
1342 .try_into()
1343 .expect("should have received the right number of bytes");
1344 self.wire_shares[gate_index] = Some((share, Some(WireLabel(label))));
1345 }
1346 _ => continue,
1347 }
1348 }
1349
1350 Ok(())
1351 }
1352
1353 fn function_dependent(
1355 &mut self,
1356 circuit: &Circuit,
1357 ) -> Result<(Vec<GarbledAnd>, Vec<(usize, u8, AuthBit)>), Error> {
1358 let num_and_triples = circuit.num_and_gates();
1359 let mut and_shares = self
1360 .random_and_shares(num_and_triples, circuit.and_bucket_size())
1361 .unwrap();
1362
1363 let mut garbled_ands = Vec::new();
1364 let mut local_ands = Vec::new();
1365 for (gate_index, gate) in circuit.gates.iter().enumerate() {
1366 match *gate {
1367 crate::circuit::WiredGate::Xor(left, right) => {
1368 let share_left = self.wire_shares[left]
1369 .clone()
1370 .expect("should have shares for all earlier wires already");
1371 let share_right = self.wire_shares[right]
1372 .clone()
1373 .expect("should have shares for all earlier wires already");
1374
1375 let xor_share = self.xor_abits(&share_left.0, &share_right.0);
1376 if self.is_evaluator() {
1377 self.wire_shares[gate_index] = Some((xor_share, None));
1378 } else {
1379 let WireLabel(left_label) = share_left
1380 .1
1381 .expect("should have labels for all earlier shares already");
1382 let WireLabel(right_label) = share_right
1383 .1
1384 .expect("should have labels for all earlier shares already");
1385 let xor_label = xor_mac_width(&left_label, &right_label);
1386 self.wire_shares[gate_index] =
1387 Some((xor_share, Some(WireLabel(xor_label))));
1388 }
1389 }
1390 crate::circuit::WiredGate::And(left, right) => {
1391 let share_left = self.wire_shares[left]
1392 .clone()
1393 .expect("should have shares for all earlier wires already");
1394 let share_right = self.wire_shares[right]
1395 .clone()
1396 .expect("should have shares for all earlier wires already");
1397
1398 let random_and_triple = and_shares
1399 .pop()
1400 .expect("should have pre-computed enough AND triples");
1401 let and_share =
1402 self.and_abits(random_and_triple, &share_left.0, &share_right.0)?;
1403
1404 let and_output_share = self.wire_shares[gate_index]
1405 .clone()
1406 .expect("should have labels for all AND gate output wires");
1407
1408 let and_0 = self.xor_abits(&and_output_share.0, &and_share);
1409 let and_1 = self.xor_abits(&and_0, &share_left.0);
1410 let and_2 = self.xor_abits(&and_0, &share_right.0);
1411 let mut and_3 = self.xor_abits(&and_1, &share_right.0);
1412
1413 if self.is_evaluator() {
1414 and_3.bit.value ^= true;
1416
1417 for _j in 1..self.num_parties {
1418 let garbled_and_message = self.channels.listen.recv().unwrap();
1419 if let Message {
1420 from,
1421 to,
1422 payload: MessagePayload::GarbledAnd(g0, g1, g2, g3),
1423 } = garbled_and_message
1424 {
1425 debug_assert_eq!(to, self.id);
1426 garbled_ands.push(GarbledAnd {
1427 sender: from,
1428 gate_index,
1429 g0,
1430 g1,
1431 g2,
1432 g3,
1433 });
1434 } else {
1435 return Err(Error::UnexpectedMessage(garbled_and_message));
1436 }
1437 }
1438
1439 for j in (1..self.num_parties).rev() {
1440 self.channels.parties[j]
1441 .send(Message {
1442 from: self.id,
1443 to: j,
1444 payload: MessagePayload::Sync,
1445 })
1446 .unwrap();
1447 }
1448 local_ands.push((gate_index, 0, and_0));
1449 local_ands.push((gate_index, 1, and_1));
1450 local_ands.push((gate_index, 2, and_2));
1451 local_ands.push((gate_index, 3, and_3));
1452 } else {
1453 let evaluator_key = and_3
1455 .mac_keys
1456 .iter_mut()
1457 .find(|key| key.bit_holder == EVALUATOR_ID)
1458 .expect("should have key for evaluator");
1459 evaluator_key.mac_key =
1460 xor_mac_width(&evaluator_key.mac_key, &self.global_mac_key);
1461
1462 let WireLabel(left_label) = share_left
1463 .1
1464 .expect("should have labels for all earlier wires");
1465 let WireLabel(right_label) = share_right
1466 .1
1467 .expect("should have labels for all earlier wires");
1468 let left_inv_label = xor_mac_width(&left_label, &self.global_mac_key);
1469 let right_inv_label = xor_mac_width(&right_label, &self.global_mac_key);
1470
1471 let WireLabel(output_label) = and_output_share.1.unwrap();
1472 let garble_0 = self.garble_and(
1473 gate_index,
1474 0,
1475 and_0,
1476 output_label,
1477 left_label,
1478 right_label,
1479 );
1480 let garble_1 = self.garble_and(
1481 gate_index,
1482 1,
1483 and_1,
1484 output_label,
1485 left_label,
1486 right_inv_label,
1487 );
1488 let garble_2 = self.garble_and(
1489 gate_index,
1490 2,
1491 and_2,
1492 output_label,
1493 left_inv_label,
1494 right_label,
1495 );
1496 let garble_3 = self.garble_and(
1497 gate_index,
1498 3,
1499 and_3,
1500 output_label,
1501 left_inv_label,
1502 right_inv_label,
1503 );
1504
1505 self.channels
1506 .evaluator
1507 .send(Message {
1508 from: self.id,
1509 to: EVALUATOR_ID,
1510 payload: MessagePayload::GarbledAnd(
1511 garble_0, garble_1, garble_2, garble_3,
1512 ),
1513 })
1514 .unwrap();
1515
1516 let sync = self.channels.listen.recv().unwrap();
1517 match sync.payload {
1518 MessagePayload::Sync => {
1519 if sync.from != EVALUATOR_ID || sync.to != self.id {
1520 return Err(Error::UnexpectedMessage(sync));
1521 }
1522 }
1523 _ => return Err(Error::UnexpectedMessage(sync)),
1524 }
1525 }
1526 }
1527 crate::circuit::WiredGate::Not(input) => {
1528 let share_input = self.wire_shares[input]
1529 .clone()
1530 .expect("should have shares for all earlier wires already");
1531
1532 let inverted_share = self.invert_abit(&share_input.0);
1533 if self.is_evaluator() {
1534 self.wire_shares[gate_index] = Some((inverted_share, None));
1535 } else {
1536 let WireLabel(input_label) = share_input
1537 .1
1538 .expect("should have labels for all earlier shares already");
1539
1540 let inverted_label = xor_mac_width(&input_label, &self.global_mac_key);
1541 self.wire_shares[gate_index] =
1542 Some((inverted_share, Some(WireLabel(inverted_label))));
1543 }
1544 }
1545 crate::circuit::WiredGate::Input(_) => continue,
1546 }
1547 }
1548
1549 Ok((garbled_ands, local_ands))
1550 }
1551
1552 pub fn input_processing(
1554 &mut self,
1555 circuit: &Circuit,
1556 input_values: &[bool],
1557 ) -> Result<(Vec<(usize, bool)>, Vec<(usize, usize, [u8; 16])>), Error> {
1558 let mut masked_wire_values = Vec::new();
1559 let mut wire_labels = Vec::new();
1560 let mut input_wire_offset = 0;
1561 for (party, input_width) in circuit.input_widths.iter().enumerate() {
1562 for input_index in 0..*input_width {
1563 let input_wire_index = input_wire_offset + input_index;
1564 let wire_share = &self.wire_shares[input_wire_index]
1565 .clone()
1566 .expect("should have wire shares for all input wires");
1567 let mut masked_wire_value;
1568 if party == self.id {
1569 let input_value = input_values[input_index];
1570 let mut other_wire_mask_shares = Vec::new();
1572 for j in 0..self.num_parties {
1573 if j == self.id {
1574 continue;
1575 }
1576
1577 let mac_message = self.channels.listen.recv().unwrap();
1578 if let Message {
1579 from,
1580 to,
1581 payload: MessagePayload::WireMac(r_j, mac_j),
1582 } = mac_message
1583 {
1584 debug_assert_eq!(to, self.id);
1585 let my_key = wire_share
1587 .0
1588 .mac_keys
1589 .iter()
1590 .find(|key| key.bit_holder == from)
1591 .expect("should have keys for all other parties");
1592 if !verify_mac(&r_j, &mac_j, &my_key.mac_key, &self.global_mac_key) {
1593 return Err(Error::CheckFailed(
1594 "invalid input wire MAC ".to_owned(),
1595 ));
1596 }
1597 other_wire_mask_shares.push(r_j);
1598 } else {
1599 return Err(Error::UnexpectedMessage(mac_message));
1600 }
1601 }
1602
1603 masked_wire_value = input_value ^ wire_share.0.bit.value;
1605 for bit in other_wire_mask_shares {
1606 masked_wire_value ^= bit;
1607 }
1608
1609 for j in (0..self.num_parties).rev() {
1611 if j == self.id {
1612 continue;
1613 }
1614 self.channels.parties[j]
1615 .send(Message {
1616 from: self.id,
1617 to: j,
1618 payload: MessagePayload::Sync,
1619 })
1620 .unwrap();
1621 }
1622
1623 self.broadcast(&vec![masked_wire_value as u8])?;
1625 } else {
1626 let their_mac = wire_share
1628 .0
1629 .macs
1630 .iter()
1631 .find(|(maccing_party, _)| *maccing_party == party)
1632 .expect("should have macs from all other parties")
1633 .1;
1634 self.channels.parties[party]
1635 .send(Message {
1636 from: self.id,
1637 to: party,
1638 payload: MessagePayload::WireMac(wire_share.0.bit.value, their_mac),
1639 })
1640 .unwrap();
1641
1642 let sync_message = self.channels.listen.recv().unwrap();
1644
1645 if !(sync_message.from == party
1646 && sync_message.to == self.id
1647 && matches!(sync_message.payload, MessagePayload::Sync))
1648 {
1649 return Err(Error::UnexpectedMessage(sync_message));
1650 }
1651
1652 masked_wire_value = self
1654 .broadcast(&[])?
1655 .iter()
1656 .find(|(sending_party, _)| *sending_party == party)
1657 .expect("should have received broadcast from all other parties")
1658 .1[0]
1659 != 0;
1660 }
1661
1662 masked_wire_values.push((input_wire_index, masked_wire_value));
1663
1664 if self.is_evaluator() {
1666 for _j in 0..self.num_parties - 1 {
1668 let label_message = self.channels.listen.recv().unwrap();
1669 if let Message {
1670 from,
1671 to,
1672 payload: MessagePayload::WireLabel { wire, label },
1673 } = label_message
1674 {
1675 debug_assert_eq!(to, self.id);
1676 debug_assert_eq!(wire, input_wire_index);
1677
1678 wire_labels.push((from, wire, label));
1679 } else {
1680 return Err(Error::UnexpectedMessage(label_message));
1681 }
1682 }
1683
1684 for j in (0..self.num_parties).rev() {
1686 if j == self.id {
1687 continue;
1688 }
1689 self.channels.parties[j]
1690 .send(Message {
1691 from: self.id,
1692 to: j,
1693 payload: MessagePayload::Sync,
1694 })
1695 .unwrap();
1696 }
1697 } else {
1698 let WireLabel(mut label) = wire_share
1700 .clone()
1701 .1
1702 .expect("should have labels for all input wires");
1703 if masked_wire_value {
1704 label = xor_mac_width(&label, &self.global_mac_key)
1705 }
1706
1707 self.channels
1708 .evaluator
1709 .send(Message {
1710 from: self.id,
1711 to: EVALUATOR_ID,
1712 payload: MessagePayload::WireLabel {
1713 wire: input_wire_index,
1714 label,
1715 },
1716 })
1717 .unwrap();
1718
1719 let sync_message = self.channels.listen.recv().unwrap();
1721
1722 if !(sync_message.from == EVALUATOR_ID
1723 && sync_message.to == self.id
1724 && matches!(sync_message.payload, MessagePayload::Sync))
1725 {
1726 return Err(Error::UnexpectedMessage(sync_message));
1727 }
1728 }
1729 }
1730
1731 input_wire_offset += input_width;
1732 }
1733
1734 Ok((masked_wire_values, wire_labels))
1735 }
1736
1737 fn evaluate_circuit(
1739 &mut self,
1740 circuit: &Circuit,
1741 garbled_ands: Vec<GarbledAnd>,
1742 local_ands: Vec<(usize, u8, AuthBit)>,
1743 masked_input_wire_values: Vec<(usize, bool)>,
1744 input_wire_labels: Vec<(usize, usize, [u8; MAC_LENGTH])>,
1745 ) -> Result<(Vec<(usize, bool)>, Vec<(usize, usize, [u8; 16])>), Error> {
1746 let mut masked_wire_values = masked_input_wire_values;
1747 let mut wire_labels = input_wire_labels;
1748 for (gate_index, gate) in circuit.gates.iter().enumerate() {
1749 match *gate {
1750 crate::circuit::WiredGate::Input(_) => continue,
1751 crate::circuit::WiredGate::Xor(left, right) => {
1752 let left_masked_value = masked_wire_values
1753 .iter()
1754 .find(|(wire_index, _)| *wire_index == left)
1755 .expect("should have labels and mask for all earlier wires")
1756 .1;
1757 let right_masked_value = masked_wire_values
1758 .iter()
1759 .find(|(wire_index, _)| *wire_index == right)
1760 .expect("should have labels and mask for all earlier wires")
1761 .1;
1762
1763 let output_wire_mask = left_masked_value ^ right_masked_value;
1764 masked_wire_values.push((gate_index, output_wire_mask));
1765
1766 for party in 1..self.num_parties {
1767 let their_left_label = wire_labels
1768 .iter()
1769 .find(|(labeling_party, wire_index, _)| {
1770 *labeling_party == party && *wire_index == left
1771 })
1772 .expect("should have labels from all parties for all earlier wires")
1773 .2;
1774 let their_right_label = wire_labels
1775 .iter()
1776 .find(|(labeling_party, wire_index, _)| {
1777 *labeling_party == party && *wire_index == right
1778 })
1779 .expect("should have labels from all parties for all earlier wires")
1780 .2;
1781 let output_wire_label =
1782 xor_mac_width(&their_left_label, &their_right_label);
1783 wire_labels.push((party, gate_index, output_wire_label));
1784 }
1785 }
1786
1787 crate::circuit::WiredGate::And(left, right) => {
1788 let output_wire_share = &self.wire_shares[gate_index]
1789 .as_ref()
1790 .expect("should have shares for all AND gates")
1791 .0;
1792 let left_masked_value = masked_wire_values
1793 .iter()
1794 .find(|(wire_index, _)| *wire_index == left)
1795 .expect("should have labels and mask for all earlier wires")
1796 .1;
1797 let right_masked_value = masked_wire_values
1798 .iter()
1799 .find(|(wire_index, _)| *wire_index == right)
1800 .expect("should have labels and mask for all earlier wires")
1801 .1;
1802
1803 let mut masked_output_value = output_wire_share.bit.value;
1804 let mut this_wires_labels = Vec::new();
1805 for j in 1..self.num_parties {
1806 let garble_index =
1807 2 * (left_masked_value as u8) + (right_masked_value as u8);
1808 let their_left_label = wire_labels
1810 .iter()
1811 .find(|(sender, gate_index, _)| *sender == j && *gate_index == left)
1812 .expect("should have labels from all other parties")
1813 .2;
1814 let their_right_label = wire_labels
1815 .iter()
1816 .find(|(sender, gate_index, _)| *sender == j && *gate_index == right)
1817 .expect("should have labels from all other parties")
1818 .2;
1819 let garbled_and_table = garbled_ands
1820 .iter()
1821 .find(|g| g.gate_index == gate_index && g.sender == j)
1822 .expect("should habe garbled and from all parties for all and gates");
1823 let garbled_and = match garble_index {
1824 0 => &garbled_and_table.g0,
1825 1 => &garbled_and_table.g1,
1826 2 => &garbled_and_table.g2,
1827 3 => &garbled_and_table.g3,
1828 _ => panic!("Invalid garble index"),
1829 };
1830 let (r_j, macs, initial_output_label) = self.ungarble_and(
1831 gate_index,
1832 garble_index,
1833 garbled_and,
1834 their_left_label,
1835 their_right_label,
1836 )?;
1837 let my_mac = macs[self.id];
1839 let my_key = local_ands
1840 .iter()
1841 .find(|(gate, garble, _)| {
1842 *gate == gate_index && *garble == garble_index
1843 })
1844 .expect("should have keys for all other parties' MACs")
1845 .2
1846 .mac_keys
1847 .iter()
1848 .find(|k| k.bit_holder == j)
1849 .unwrap();
1850 if !verify_mac(&r_j, &my_mac, &my_key.mac_key, &self.global_mac_key) {
1851 return Err(Error::CheckFailed(
1852 "AND gate evaluation: MAC check failed".to_owned(),
1853 ));
1854 }
1855 masked_output_value ^= r_j;
1856 let mut their_output_wire_label = initial_output_label;
1857 for mac in macs {
1858 their_output_wire_label = xor_mac_width(&their_output_wire_label, &mac);
1859 }
1860 this_wires_labels.push((j, their_output_wire_label));
1861 wire_labels.push((j, gate_index, their_output_wire_label));
1862 }
1863
1864 masked_wire_values.push((gate_index, masked_output_value));
1865 }
1866
1867 crate::circuit::WiredGate::Not(before) => {
1868 let before_masked_value = masked_wire_values
1869 .iter()
1870 .find(|(wire_index, _)| *wire_index == before)
1871 .expect("should have labels and mask for all earlier wires")
1872 .1;
1873 let output_wire_mask = before_masked_value ^ true;
1874 masked_wire_values.push((gate_index, output_wire_mask));
1875 for j in 1..self.num_parties {
1876 let their_label = wire_labels
1877 .iter()
1878 .find(|(sender, gate_index, _)| *sender == j && *gate_index == before)
1879 .expect("should have labels for all earlier wires")
1880 .2;
1881 wire_labels.push((j, gate_index, their_label)); }
1883 }
1884 }
1885 }
1886 Ok((masked_wire_values, wire_labels))
1887 }
1888
1889 pub fn output_processing(
1891 &mut self,
1892 circuit: &Circuit,
1893 masked_wire_values: Vec<(usize, bool)>,
1894 ) -> Result<Vec<(usize, bool)>, Error> {
1895 let mut output_values = Vec::new();
1896 for output_wire_index in circuit.output_gates.iter() {
1898 let output_wire_share = &self.wire_shares[*output_wire_index]
1899 .clone()
1900 .expect("should have wire shares for all input wires")
1901 .0;
1902 if self.is_evaluator() {
1903 let mut output_wire_value = masked_wire_values
1904 .iter()
1905 .find(|(wire_index, _)| *wire_index == *output_wire_index)
1906 .expect("should have masked values for all output wires after evaluation")
1907 .1;
1908 for _j in 0..self.num_parties - 1 {
1909 let share_message = self.channels.listen.recv().unwrap();
1910 if let Message {
1911 from,
1912 to,
1913 payload: MessagePayload::WireMac(wire_mask_share, mac),
1914 } = share_message
1915 {
1916 debug_assert_eq!(to, self.id);
1917 let my_key = output_wire_share
1919 .mac_keys
1920 .iter()
1921 .find(|key| key.bit_holder == from)
1922 .expect("should have keys for all other parties");
1923 if !verify_mac(
1924 &wire_mask_share,
1925 &mac,
1926 &my_key.mac_key,
1927 &self.global_mac_key,
1928 ) {
1929 return Err(Error::CheckFailed("invalid nput wire MAC ".to_owned()));
1930 }
1931 output_wire_value ^= wire_mask_share;
1932 } else {
1933 return Err(Error::UnexpectedMessage(share_message));
1934 }
1935 }
1936
1937 output_values.push((*output_wire_index, output_wire_value));
1938
1939 for j in (0..self.num_parties).rev() {
1941 if j == self.id {
1942 continue;
1943 }
1944 self.channels.parties[j]
1945 .send(Message {
1946 from: self.id,
1947 to: j,
1948 payload: MessagePayload::Sync,
1949 })
1950 .unwrap();
1951 }
1952 } else {
1953 let evaluator_mac = output_wire_share.macs[EVALUATOR_ID].1;
1955 self.channels
1956 .evaluator
1957 .send(Message {
1958 from: self.id,
1959 to: EVALUATOR_ID,
1960 payload: MessagePayload::WireMac(
1961 output_wire_share.bit.value,
1962 evaluator_mac,
1963 ),
1964 })
1965 .unwrap();
1966
1967 let sync_message = self.channels.listen.recv().unwrap();
1969
1970 if !(sync_message.from == EVALUATOR_ID
1971 && sync_message.to == self.id
1972 && matches!(sync_message.payload, MessagePayload::Sync))
1973 {
1974 return Err(Error::UnexpectedMessage(sync_message));
1975 }
1976 }
1977 }
1978
1979 Ok(output_values)
1980 }
1981
1982 pub fn run(
1984 &mut self,
1985 read_stored_triples: bool,
1986 circuit: &Circuit,
1987 input: &[bool],
1988 ) -> Result<Option<Vec<(usize, bool)>>, Error> {
1989 use std::io::Write;
1990
1991 circuit
1993 .validate_circuit_specification()
1994 .map_err(Error::Circuit)
1995 .unwrap();
1996
1997 if circuit.input_widths[self.id] != input.len() {
1998 panic!("Invalid input provided to party {}", self.id)
1999 }
2000
2001 let num_auth_shares = circuit.share_authentication_cost() + SEC_MARGIN_SHARE_AUTH;
2002
2003 if read_stored_triples {
2004 let file = std::fs::File::open(format!("{}.triples", self.id));
2005 if let Ok(f) = file {
2006 (self.global_mac_key, self.abit_pool) =
2007 serde_json::from_reader(f).map_err(|_| Error::OtherError)?;
2008
2009 let max_id = self
2010 .abit_pool
2011 .iter()
2012 .max_by_key(|abit| abit.bit.id.0)
2013 .map(|abit| abit.bit.id.0)
2014 .unwrap_or(0);
2015 self.bit_counter = max_id;
2016
2017 if num_auth_shares > self.abit_pool.len() {
2018 self.log(&format!(
2019 "Insufficient precomputation (by {})",
2020 num_auth_shares - self.abit_pool.len()
2021 ));
2022 return Ok(None);
2023 }
2024 }
2025 } else {
2026 let target_number = circuit.share_authentication_cost();
2027
2028 self.abit_pool = self.precompute_abits(target_number + SEC_MARGIN_SHARE_AUTH)?;
2029
2030 let file = std::fs::File::create(format!("{}.triples", self.id))
2031 .map_err(|_| Error::OtherError)?;
2032 let mut writer = std::io::BufWriter::new(file);
2033 serde_json::to_writer(&mut writer, &(self.global_mac_key, &self.abit_pool))
2034 .map_err(|_| Error::OtherError)?;
2035 writer.flush().unwrap();
2036 }
2037
2038 self.function_independent(circuit).unwrap();
2039
2040 let (garbled_ands, local_ands) = self.function_dependent(circuit).unwrap();
2041 if self.is_evaluator() {
2042 debug_assert_eq!(
2043 garbled_ands.len(),
2044 circuit.num_and_gates() * (self.num_parties - 1)
2045 );
2046 }
2047
2048 self.sync().unwrap();
2049
2050 let (masked_input_wire_values, input_wire_labels) =
2051 self.input_processing(circuit, input).unwrap();
2052
2053 self.sync().unwrap();
2054 let result = if self.is_evaluator() {
2055 let (masked_wire_values, _wire_labels) = self
2056 .evaluate_circuit(
2057 circuit,
2058 garbled_ands,
2059 local_ands,
2060 masked_input_wire_values,
2061 input_wire_labels,
2062 )
2063 .unwrap();
2064 self.sync().unwrap();
2065 let result = self.output_processing(circuit, masked_wire_values).unwrap();
2066
2067 self.log(&format!("Got result {result:?}"));
2068 result
2069 } else {
2070 self.sync().unwrap();
2071 let result = self
2072 .output_processing(circuit, masked_input_wire_values)
2073 .unwrap();
2074
2075 result
2076 };
2077
2078 Ok(if result.is_empty() {
2079 Some(result)
2080 } else {
2081 None
2082 })
2083 }
2084
2085 fn sync(&self) -> Result<(), Error> {
2098 for _i in (self.id + 1..self.num_parties).rev() {
2099 let sync_msg = self
2100 .channels
2101 .listen
2102 .recv()
2103 .expect("all parties should be online");
2104 if let MessagePayload::Sync = sync_msg.payload {
2105 continue;
2106 } else {
2107 return Err(Error::UnexpectedMessage(sync_msg));
2108 }
2109 }
2110
2111 for i in (0..self.num_parties).rev() {
2112 if i == self.id {
2113 continue;
2114 }
2115 self.channels.parties[i]
2116 .send(Message {
2117 from: self.id,
2118 to: i,
2119 payload: MessagePayload::Sync,
2120 })
2121 .expect("all parties should be online");
2122 }
2123
2124 for _ in (0..self.id).rev() {
2125 let sync_msg = self
2126 .channels
2127 .listen
2128 .recv()
2129 .expect("all parties should be online");
2130 if let MessagePayload::Sync = sync_msg.payload {
2131 continue;
2132 } else {
2133 return Err(Error::UnexpectedMessage(sync_msg));
2134 }
2135 }
2136
2137 Ok(())
2138 }
2139
2140 fn log(&mut self, message: &str) {
2142 if self.enable_logging {
2143 eprintln!("[Party {} @ {}]: {}", self.id, self.log_counter, message);
2144 self.log_counter += 1;
2145 }
2146 }
2147
2148 fn garble_and(
2150 &self,
2151 gate_index: usize,
2152 garble_index: u8,
2153 and_share: AuthBit,
2154 output_label: [u8; 16],
2155 left_label: [u8; 16],
2156 right_label: [u8; 16],
2157 ) -> Vec<u8> {
2158 let garble_serialization: Vec<u8> = self.garbling_serialize(and_share, output_label);
2159 let blinding: Vec<u8> = compute_blinding(
2160 garble_serialization.len(),
2161 left_label,
2162 right_label,
2163 gate_index,
2164 garble_index,
2165 );
2166 let mut result = vec![0u8; garble_serialization.len()];
2167 for byte in 0..result.len() {
2168 result[byte] = garble_serialization[byte] ^ blinding[byte];
2169 }
2170 result
2171 }
2172
2173 fn ungarble_and(
2175 &self,
2176 gate_index: usize,
2177 garble_index: u8,
2178 garbled_and: &[u8],
2179 left_label: [u8; 16],
2180 right_label: [u8; 16],
2181 ) -> Result<(bool, Vec<[u8; MAC_LENGTH]>, [u8; MAC_LENGTH]), Error> {
2182 let blinding: Vec<u8> = compute_blinding(
2183 garbled_and.len(),
2184 left_label,
2185 right_label,
2186 gate_index,
2187 garble_index,
2188 );
2189 let mut result_bytes = vec![0u8; garbled_and.len()];
2190 for byte in 0..result_bytes.len() {
2191 result_bytes[byte] = garbled_and[byte] ^ blinding[byte];
2192 }
2193
2194 let result = self.garbling_deserialize(&result_bytes)?;
2195 Ok(result)
2196 }
2197
2198 fn garbling_serialize(&self, and_share: AuthBit, output_label: [u8; 16]) -> Vec<u8> {
2200 let mut result = and_share.serialize_bit_macs();
2201 let mut garbled_label = output_label;
2202 for key in and_share.mac_keys {
2203 garbled_label = xor_mac_width(&garbled_label, &key.mac_key);
2204 }
2205
2206 if and_share.bit.value {
2207 garbled_label = xor_mac_width(&garbled_label, &self.global_mac_key);
2208 }
2209 result.extend_from_slice(&garbled_label);
2210 result
2211 }
2212
2213 fn garbling_deserialize(
2215 &self,
2216 serialization: &[u8],
2217 ) -> Result<(bool, Vec<[u8; 16]>, [u8; 16]), Error> {
2218 let (bit_mac_bytes, label) = serialization.split_at(1 + MAC_LENGTH * self.num_parties);
2219 let (bit_value, macs) = AuthBit::deserialize_bit_macs(bit_mac_bytes)?;
2220 Ok((bit_value, macs, label.try_into().unwrap()))
2221 }
2222}
2223
2224fn compute_blinding(
2225 len: usize,
2226 left_label: [u8; 16],
2227 right_label: [u8; 16],
2228 gate_index: usize,
2229 garble_index: u8,
2230) -> Vec<u8> {
2231 let mut ikm = vec![garble_index];
2232 ikm.extend_from_slice(&left_label);
2233 ikm.extend_from_slice(&right_label);
2234 ikm.extend_from_slice(&gate_index.to_be_bytes());
2235 let domain_separator = "garble-blinding";
2236 let prekey = hkdf_extract(domain_separator.as_bytes(), &ikm);
2237 hkdf_expand(&prekey, b"", len)
2238}