fancy_garbling/garble/
binary_and.rs1use crate::{WireLabel, WireMod2, hash_wires, util::tweak2};
2use fancy_traits::HasModulus;
3use subtle::ConditionallySelectable;
4use vectoreyes::U8x16;
5
6pub trait BinaryWireLabel: WireLabel + ConditionallySelectable {
9 fn garble_and_gate(gate_num: usize, A: &Self, B: &Self, delta: &Self) -> (U8x16, U8x16, Self);
14
15 fn evaluate_and_gate(gate_num: usize, A: &Self, B: &Self, gate0: &U8x16, gate1: &U8x16)
19 -> Self;
20}
21
22impl BinaryWireLabel for WireMod2 {
23 fn garble_and_gate(gate_num: usize, A: &Self, B: &Self, delta: &Self) -> (U8x16, U8x16, Self) {
24 let q = A.modulus();
25 let D = delta;
26
27 let r = B.color(); let g = tweak2(gate_num as u64, 0);
30
31 let alpha = A.color(); let X1 = *A + *D * alpha;
34
35 let beta = (q - B.color()) % q;
37 let Y1 = *B + *D * beta;
38
39 let AD = *A + *D;
40 let BD = *B + *D;
41
42 let a_selector = (A.color() as u8).into();
44 let b_selector = (B.color() as u8).into();
45
46 let B = Self::conditional_select(&BD, B, b_selector);
47 let newA = Self::conditional_select(&AD, A, a_selector);
48 let idx = u8::conditional_select(&(r as u8), &0u8, a_selector);
49
50 let [hashA, hashB, hashX, hashY] = hash_wires([&newA, &B, &X1, &Y1], g);
51
52 let X = Self::hash_to_mod(hashX, q) + *D * (alpha * r % q);
53 let Y = Self::hash_to_mod(hashY, q);
54
55 let gate0 =
56 hashA ^ U8x16::conditional_select(&X.to_repr(), &(X + *D).to_repr(), idx.into());
57 let gate1 = hashB ^ (Y + *A).to_repr();
58
59 (gate0, gate1, X + Y)
60 }
61
62 fn evaluate_and_gate(
63 gate_num: usize,
64 A: &Self,
65 B: &Self,
66 gate0: &U8x16,
67 gate1: &U8x16,
68 ) -> Self {
69 let g = tweak2(gate_num as u64, 0);
70
71 let [hashA, hashB] = hash_wires([A, B], g);
72
73 let L = Self::from_repr(
75 U8x16::conditional_select(&hashA, &(hashA ^ *gate0), (A.color() as u8).into()),
76 2,
77 );
78
79 let R = Self::from_repr(
81 U8x16::conditional_select(&hashB, &(hashB ^ *gate1), (B.color() as u8).into()),
82 2,
83 );
84
85 L + R + *A * B.color()
86 }
87}