fancy_garbling/circuits/
aes.rs1use crate::{
4 FancyBinary,
5 circuit::{BinaryCircuit, Circuit, CircuitInputMapper},
6};
7use std::io::Cursor;
8use swanky_channel::Channel;
9use swanky_error::Result;
10
11pub struct AesNonExpanded(BinaryCircuit);
15
16impl AesNonExpanded {
17 pub fn new() -> Self {
24 let circuit = BinaryCircuit::parse_bristol_format(Cursor::<&'static [u8]>::new(
25 include_bytes!("../../circuits/bristol-format/AES-non-expanded.txt"),
26 ))
27 .expect("`AES-non-expanded.txt` file should always parse correctly");
28 Self(circuit)
29 }
30}
31
32impl Default for AesNonExpanded {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl<F: FancyBinary> Circuit<F> for AesNonExpanded {
39 type Input = ([F::Item; 128], [F::Item; 128]);
40 type Output = [F::Item; 128];
41
42 fn execute(
43 &self,
44 backend: &mut F,
45 inputs: Self::Input,
46 channel: &mut Channel,
47 ) -> Result<Self::Output> {
48 let mut combined = inputs.1.to_vec();
54 combined.extend_from_slice(&inputs.0);
55 let output = self.0.execute(backend, combined, channel)?;
56 Ok(output
57 .try_into()
58 .expect("AES output should always be 128 elements"))
59 }
60}
61
62impl<F: FancyBinary> CircuitInputMapper<F> for AesNonExpanded {
63 fn map(&self, inputs: Vec<<F as crate::Fancy>::Item>) -> Self::Input {
64 assert_eq!(inputs.len(), 256);
65 let (key, block) = inputs.split_at(128);
66 (
67 key.to_vec().try_into().unwrap(),
68 block.to_vec().try_into().unwrap(),
69 )
70 }
71
72 fn ninputs(&self) -> usize {
73 256
74 }
75
76 fn modulus(&self, _: usize) -> u16 {
77 2
78 }
79}
80
81#[cfg(test)]
82mod test {
83 use super::*;
84
85 #[test]
86 fn aes_non_expanded() {
87 use crate::dummy::{Dummy, DummyVal};
88
89 let aes = AesNonExpanded::new();
90
91 let key = [DummyVal::new(0, 2); 128];
92 let block = [DummyVal::new(0, 2); 128];
93 let output = Dummy::eval(&aes, (key, block)).unwrap();
94 assert_eq!(
95 output
96 .iter()
97 .map(|i| i.val().to_string())
98 .collect::<String>(),
99 "01100110111010010100101111010100111011111000101000101100001110111000100001001100111110100101100111001010001101000010101100101110"
100 );
101
102 let key = [DummyVal::new(1, 2); 128];
103 let block = [DummyVal::new(0, 2); 128];
104 let output = Dummy::eval(&aes, (key, block)).unwrap();
105 assert_eq!(
106 output
107 .iter()
108 .map(|i| i.val().to_string())
109 .collect::<String>(),
110 "10100001111101100010010110001100100001110111110101011111110011011000100101100100010010000100010100111000101111111100100100101100"
111 );
112
113 let mut key = [DummyVal::new(0, 2); 128];
114 for key_part in key.iter_mut().take(8) {
115 *key_part = DummyVal::new(1, 2);
116 }
117 let block = [DummyVal::new(0, 2); 128];
118 let output = Dummy::eval(&aes, (key, block)).unwrap();
119 assert_eq!(
120 output
121 .iter()
122 .map(|i| i.val().to_string())
123 .collect::<String>(),
124 "10110001110101110101100000100101011010110010100011111101100001010000101011010100100101000100001000001000110011110001000101010101"
125 );
126
127 let mut key = [DummyVal::new(0, 2); 128];
128 key[7] = DummyVal::new(1, 2);
129 let block = [DummyVal::new(0, 2); 128];
130 let output = Dummy::eval(&aes, (key, block)).unwrap();
131 assert_eq!(
132 output
133 .iter()
134 .map(|i| i.val().to_string())
135 .collect::<String>(),
136 "11011100000011101101100001011101111110010110000100011010101110110111001001001001110011011101000101101000110001010100011001111110"
137 );
138 }
139
140 #[test]
141 fn aes_non_expanded_gc_eval() {
142 use crate::{WireMod2, classic::GarbledCircuit};
143 use swanky_rng::SwankyRng;
144
145 let aes = AesNonExpanded::new();
146
147 let (encoder, gc, _) =
148 GarbledCircuit::garble::<WireMod2, _, _>(&aes, SwankyRng::new()).unwrap();
149 let inputs = encoder.encode_inputs(&vec![0u16; 256]);
150 let key = inputs[..128].try_into().unwrap();
151 let block = inputs[128..].try_into().unwrap();
152 gc.eval_to_wirelabels(&aes, (key, block)).unwrap();
153 }
154}