fancy_garbling/circuits/arithmetic/
mod_change.rs1use crate::{Circuit, FancyProj, HasModulus};
2use swanky_channel::Channel;
3use swanky_error::Result;
4
5pub struct ModChange;
7
8impl<F: FancyProj> Circuit<F> for ModChange {
9 type Input = (F::Item, u16);
10 type Output = F::Item;
11
12 fn execute(
13 &self,
14 backend: &mut F,
15 inputs: Self::Input,
16 channel: &mut Channel,
17 ) -> Result<Self::Output> {
18 let (x, to_modulus) = inputs;
19
20 let from_modulus = x.modulus();
21 if from_modulus == to_modulus {
22 return Ok(x.clone());
23 }
24 let tab = (0..from_modulus)
25 .map(|x| x % to_modulus)
26 .collect::<Vec<_>>();
27 backend.proj(&x, to_modulus, Some(tab), channel)
28 }
29}
30
31#[cfg(test)]
32mod test {
33 use crate::{
34 circuits::arithmetic::ModChange,
35 dummy::{Dummy, DummyVal},
36 util::RngExt,
37 };
38 use rand::{Rng, thread_rng};
39
40 #[test]
41 fn mod_change() {
42 let mut rng = thread_rng();
43 for _ in 0..16 {
44 let q = rng.gen_prime();
45 let p = rng.gen_prime();
46
47 let x = rng.r#gen::<u16>() % q;
48 let x_input = DummyVal::new(x, q);
49 let z = Dummy::eval(&ModChange, (x_input, p)).unwrap();
50 assert_eq!(z.val(), x % p);
51 }
52 }
53}