mpc_engine/
party.rs

1//! This module defines the behaviour of protocol parties in the different
2//! phases of the protocol.
3
4use 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
24/// Additional bit authentications computed for malicious security checks.
25const SEC_MARGIN_BIT_AUTH: usize = 2 * STATISTICAL_SECURITY * 8;
26/// Additional cost of authenticating a number of bits into authenticated shares.
27pub(crate) const SEC_MARGIN_SHARE_AUTH: usize = STATISTICAL_SECURITY * 8;
28
29const EVALUATOR_ID: usize = 0;
30
31/// Collects all party communication channels.
32///
33/// It includes
34/// - `listen`: The party's own message receiver handle
35/// - `evaluator`: The sender handle for the designated evaluator party
36/// - `parties`: All other parties' sender handles, ordered by their `id`s
37/// - `broadcast`: The sender handle of the broadcast utility
38/// - `id`: The owning parties `id`
39pub 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    /// The channel config is for the party of this ID.
45    pub id: usize,
46}
47
48/// A Wire label given by a party.
49#[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
61/// A struct defining protocol party state during a protocol execution.
62pub struct Party {
63    bit_counter: usize,
64    /// The party's numeric identifier
65    id: usize,
66    /// The number of parties in the MPC session
67    num_parties: usize,
68    /// The channel configuration for communicating to other protocol parties
69    channels: ChannelConfig,
70    /// The global MAC key for authenticating wire value shares
71    global_mac_key: MacKey,
72    /// A local source of random bits and bytes
73    entropy: Randomness,
74    /// Pool of pre-computed authenticated bits
75    abit_pool: Vec<AuthBit>,
76    /// Pool of pre-computed authenticated shares
77    ashare_pool: Vec<AuthBit>,
78    /// Whether to log events
79    enable_logging: bool,
80    /// Incremental counter for ordering logs
81    log_counter: u128,
82    /// Wire labels for every wire in the circuit
83    wire_shares: Vec<Option<(AuthBit, Option<WireLabel>)>>,
84}
85
86impl Party {
87    /// Initialize an MPC party.
88    ///
89    /// This generates the party's global MAC key and sets the protocol phase to
90    /// `PreInit`.
91    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    /// Broadcast a `value` and receive other parties' broadcasted values in
113    /// turn.
114    ///
115    /// Broadcast works using the broadcast relay utility:
116    /// - In a first step, compute a cryptographic commitment on `value` and
117    /// send that individually to all other parties.
118    /// - Then send the commitment opening to the broadcast relay.
119    /// - Finally, receive the other parties commitment openings from the
120    ///   broadcast relay and use them to open their commitments to their
121    ///   values.
122    ///
123    /// Since every party can only send one opening value to the broadcast
124    /// relay, which is assumed to be trusted in distributing the received
125    /// openings faithfully, it is ensured that every commitment is opened with
126    /// the opening information. Therefore, because the commitments are binding,
127    /// if a malicious party sends differing commitments to different parties at
128    /// least one opening must fail.
129    ///
130    /// In a non-blackbox way we can also see that parties cannot chose their
131    /// broadcast values dependent on other parties' values: Beside being
132    /// hiding, the Random Oracle commitment we use also does not allow any
133    /// homomorphic operations on commitment values, so even given many
134    /// commitments from other parties a malicious party should not be able to
135    /// chose their commitment in a way that the committed value is dependent on
136    /// other parties' committed values.
137    fn broadcast(&mut self, value: &[u8]) -> Result<Vec<(usize, Vec<u8>)>, Error> {
138        // send/receive commitment to/from all parties
139        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        // Expect earlier parties' commitments.
145        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        // All earlier commitments have been received, so it is the party's turn
161        // to send messages to everyone, except itself.
162        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        // Wait for the commitments sent by later parties.
177        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        // Send the opening to the broadcast relay.
195        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        // Receive n-1 openings from the broadcast relay.
205        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    /// Broadcast three commitments for the share authentication malicious security check.
230    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    /// Broadcast opening values for the share authentication malicious security check.
267    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    /// Return `true`, if the party is the designated circuit evaluator.
284    fn is_evaluator(&self) -> bool {
285        self.id == EVALUATOR_ID
286    }
287
288    /// Jointly compute `len` bit authentications.
289    ///
290    /// Internally generates `len +  SEC_MARGIN_BIT_AUTH` bit
291    /// authentications for each other party, of which all but `len` are
292    /// discarded after performing statistical checks for malicious security.
293    /// After this point the guarantee is that a pair-wise consistent
294    /// `global_mac_key` was used in all bit-authentications between two
295    /// parties.
296    fn precompute_abits(&mut self, len: usize) -> Result<Vec<AuthBit>, Error> {
297        let len_unchecked = len + SEC_MARGIN_BIT_AUTH;
298
299        // 1. Generate `len_unchecked` random local bits for authenticating.
300        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        // 2. Obliviously get MACs on all local bits from every other party and obliviously provide MACs on
315        //    their local bits.
316        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            // Obliviously authenticate local bits of earlier parties.
322            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            // Obliviously obtain MACs on the current bit from all other parties.
328            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            // Obliviously authenticate local bits of later parties.
338            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        // 3. Perform the statistical check for malicious security of the
355        //    generated authenticated bits. Failure indicates buggy bit
356        //    authentication or cheating.
357        self.bit_auth_check(&authenticated_bits)
358            .expect("bit authentication check must not fail");
359
360        // 4. Return the first `len` authenticated bits.
361        Ok(authenticated_bits[0..len].to_vec())
362    }
363
364    /// Transform authenticated bits into `len` authenticated bit shares.
365    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        // Malicious security checks
370        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]; // XOR of all auth keys
376            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]; // XOR of all (auth keys xor Delta)
383            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(); // the authenticated bit and all macs on it
390
391            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            // open the other parties commitments to obtain their bit values and MACs
406            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            // compute xor of all opened MACs for each party
425            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                    // don't need to compute this for ourselves
430                    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            // compute our own xor of all bits
458            for (_party, (bit, _macs)) in other_bits_macs.iter() {
459                b_i ^= *bit;
460            }
461
462            // compute the other parties xor-ed bits to know which openings they are sending
463            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    /// Compute unauthenticated cross terms in an AND triple output share.
509    fn half_and(&mut self, x: &AuthBit, y: &AuthBit) -> Result<bool, Error> {
510        /// Obtain the least significant bit of some hash output
511        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        // receive earlier hashes
521        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            // K_i[x^j]
559            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            // K_i[x^j] xor Delta_i
567            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        // receive later hashes
584        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    /// Compute authenticated AND triples.
625    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            // Triple Check
655            // 4. compute Phi
656            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            // 5. receive earlier Us
672            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                    // compute M_phi
685                    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            // 5. send out own Us
703            for j in 0..self.num_parties {
704                if j == self.id {
705                    continue;
706                }
707                // compute k_phi
708                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                // compute U_j
718                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            // 5. Receive later Us
735            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                    // compute M_phi
745                    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            // 6. Compute H_i
765            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            // 6. Broadcast H_is
794            let other_hs = self.broadcast(&h)?;
795
796            // 7. Check H_is xor to 0
797            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    /// Verifiably open an authenticated bit, revealing its value to all parties.
818    fn open_bit(&mut self, bit: &AuthBit) -> Result<bool, Error> {
819        let mut other_bits = Vec::new();
820
821        // receive earlier parties MACs and verify them
822        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        // send out own MACs
846        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        // receive later parties MACs and verify them
865        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    /// Locally compute the XOR of two authenticated bits, which will itself be
899    /// authenticated already.
900    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), // XXX: We can't know their bit ID here, is it necessary for anything though?
930                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    /// Invert an authenticated bit, resulting in an authentication of the
970    /// inverted bit.
971    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    /// Build oblivious AND triples by combining leaky AND triples.
988    fn random_and_shares(
989        &mut self,
990        len: usize,
991        bucket_size: usize,
992    ) -> Result<Vec<(AuthBit, AuthBit, AuthBit)>, Error> {
993        // get `len * BUCKET_SIZE` leaky ANDs
994        let leaky_ands = self.random_leaky_and(len * bucket_size)?;
995
996        // Shuffle the list.
997        // Using random u128 bit indices for shuffling should prevent collisions
998        // for at least 2^40 triples except with probability 2^-40.
999        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        // combine all buckets to single ANDs
1012        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    /// Perform the active_security check for bit authentication
1033    fn bit_auth_check(&mut self, auth_bits: &[AuthBit]) -> Result<(), Error> {
1034        for _j in 0..SEC_MARGIN_BIT_AUTH {
1035            // a) Sample `ell'` random bit.s
1036            let r = self.coin_flip(auth_bits.len())?;
1037
1038            // b) Compute x_j = XOR_{m in [ell']} r_m & x_m
1039            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            // broadcast x_j
1045            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            // c) Compute xored keys for other parties
1056            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            // d) Receive / Send xored MACs
1074            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            // verify MACs
1123            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    /// Jointly sample a random byte string of length `len / 8 + 1`, i.e. enough
1140    /// to contain `len` random bits.
1141    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    /// Initiate an OT session as the Sender.
1165    ///
1166    /// The sender needs to provide two inputs to the OT protocol and receives
1167    /// no output.
1168    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    /// Listen for an OT initiation as the receiver.
1198    ///
1199    /// The receiver needs to provide a choice of left or right sender input to
1200    /// the protocol and receives the chosen sender input.
1201    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    /// Generate a fresh bit id, increasing the internal bit counter.
1233    fn fresh_bit_id(&mut self) -> BitID {
1234        let res = self.bit_counter;
1235        self.bit_counter += 1;
1236        BitID(res)
1237    }
1238
1239    /// Initiate a two-party bit authentication session to oblivious obtain a
1240    /// MAC from the authenticator on a locally held bit.
1241    ///
1242    /// The authenticator computes `left_value = K + Delta` and `right_value =
1243    /// K` where `K` is a fresh mac key and `Delta` is the authenticator's
1244    /// global MAC key. If `b` is the bit holders local bit, the bit holder can
1245    /// thus obliviously obtain a MAC `M = K + b * Delta` by setting `b` as
1246    /// their choice bit as an OT receiver with the authenticator acting as OT
1247    /// sender with inputs `left_value` and `right value`.
1248    fn obtain_bit_authentication(
1249        &mut self,
1250        authenticator: usize,
1251        local_bit: &Bit,
1252    ) -> Result<Mac, Error> {
1253        // Set up channels for an OT subprotocol session with the authenticator.
1254        let (my_address, my_inbox) = mpsc::channel::<SubMessage>();
1255        let (their_address, their_inbox) = mpsc::channel::<SubMessage>();
1256
1257        // The authenticator has to initiate an OT session, so request a bit
1258        // authentication session using the generated channels.
1259        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        // Join the authenticator's OT session with the local bit value as the
1272        // receiver choice input.
1273        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    /// Listen for a two-party bit authentication request to oblivious
1282    /// authenticate a bit holders local bit and obtain the corresponding MAC
1283    /// key.
1284    ///
1285    /// The authenticator computes `left_value = K + Delta` and `right_value =
1286    /// K` where `K` is a fresh mac key and `Delta` is the authenticator's
1287    /// global MAC key. If `b` is the bit holders local bit, the bit holder can
1288    /// thus obliviously obtain a MAC `M = K + b * Delta` by setting `b` as
1289    /// their choice bit as an OT receiver with the authenticator acting as OT
1290    /// sender with inputs `left_value` and `right value`.
1291    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            // Compute the MACs for both possible values of the bit holder's
1307            // bit. Note that `mac_on_false` is simply the fresh local mac_key.
1308            let (mac_on_true, mac_on_false) = mac(&true, &self.global_mac_key, &mut self.entropy);
1309
1310            // Initiate an OT session with the bit holder giving the two MACs as
1311            // sender inputs.
1312            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    /// Run the function independent pre-processing phase of the protocol.
1326    ///
1327    /// This generates labeled wire shares for all input wires and AND-gate output wires.
1328    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    /// Run the function-dependent pre-processing phase of the protocol.
1354    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                        // do local computation and receive values
1415                        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                        // do local computation and send values
1454                        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    /// Run the input-processing phase of the protocol.
1553    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                    // receive input wire shares from the other parties
1571                    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                            // verify mac
1586                            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                    // compute blinded input value
1604                    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                    // acknowledge received messages
1610                    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                    // Broadcast masked wire. Don't care about other parties' values here.
1624                    self.broadcast(&vec![masked_wire_value as u8])?;
1625                } else {
1626                    // send input wire shares to the party
1627                    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                    // receive acknowlegement
1643                    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                    // receive masked wire value broadcast
1653                    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                // Send correct wire label to evaluator.
1665                if self.is_evaluator() {
1666                    // listen for all wire labels
1667                    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                    // acknowledge received messages
1685                    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                    // send my wire label according to the received / computed wire_mask
1699                    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                    // listen for acknowledgement
1720                    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    /// Run the circuit evaluation phase of the protocol.
1738    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                        // recover output wire shares and labels from garbled tables
1809                        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                        // check my MAC on recovered share
1838                        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)); // XXX: Label stays the same here. OK?
1882                    }
1883                }
1884            }
1885        }
1886        Ok((masked_wire_values, wire_labels))
1887    }
1888
1889    /// Run the output processing phase of the protocol
1890    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        // receive output wire mask shares
1897        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                        // verify mac
1918                        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                // acknowledge received messages
1940                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                // send output wire mask shares
1954                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                // listen for acknowledgement
1968                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    /// Run the MPC protocol, returning the parties output, if any.
1983    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        // Validate the circuit
1992        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    /// Synchronise parties.
2086    ///
2087    /// In all other communication rounds, parties send in increasing order of
2088    /// their numeric identifiers. In order to prevent early parties from
2089    /// advancing to the next phase of the procotol before later parties have
2090    /// caught up, this synchronization mechanism reverses the turn order,
2091    /// making numerically smaller ID parties first wait for the synchronisation
2092    /// signal from numerically larger ID parties.
2093    ///
2094    /// For this to work as a synchronisation mechanism it is crucial that
2095    /// synchronisation is the only communication round with decreasing turn
2096    /// order.
2097    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    /// Utility function to provide debug output during the protocol run.
2141    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    /// Compute an entry in a garbled AND-gate evaluation table.
2149    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    /// Ungarble an AND-gate evaluation table entry.
2174    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    /// Serialize an authenticated wire share for garbling AND gates.
2199    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    /// Deserialize an authenticated wire share for garbled AND evaluation.
2214    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}