arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/rlwe/examples/rlk_experiments.rs
rlwe/examples/rlk_experiments.rsRaw
  1use base2k::{
  2    Encoding, Infos, Module, Sampling, SvpPPol, SvpPPolOps, VecZnx, VecZnxDftOps, VecZnxOps,
  3    VmpPMat, VmpPMatOps, is_aligned,
  4};
  5use itertools::izip;
  6use rlwe::ciphertext::{Ciphertext, new_gadget_ciphertext};
  7use rlwe::elem::ElemCommon;
  8use rlwe::encryptor::encrypt_rlwe_sk;
  9use rlwe::keys::SecretKey;
 10use rlwe::plaintext::Plaintext;
 11use sampling::source::{Source, new_seed};
 12
 13fn main() {
 14    let n: usize = 32;
 15    let module: Module = Module::new(n, base2k::MODULETYPE::FFT64);
 16    let log_base2k: usize = 16;
 17    let log_k: usize = 32;
 18    let cols: usize = 4;
 19
 20    let mut a: VecZnx = module.new_vec_znx(cols);
 21    let mut data: Vec<i64> = vec![0i64; n];
 22    data[0] = 0;
 23    data[1] = 0;
 24    a.encode_vec_i64(log_base2k, log_k, &data, 16);
 25
 26    let mut a_dft: base2k::VecZnxDft = module.new_vec_znx_dft(cols);
 27
 28    module.vec_znx_dft(&mut a_dft, &a, cols);
 29
 30    (0..cols).for_each(|i| {
 31        println!("{:?}", a_dft.at::<f64>(&module, i));
 32    })
 33}
 34
 35pub struct GadgetCiphertextProtocol {}
 36
 37impl GadgetCiphertextProtocol {
 38    pub fn new() -> GadgetCiphertextProtocol {
 39        Self {}
 40    }
 41
 42    pub fn allocate(
 43        module: &Module,
 44        log_base2k: usize,
 45        rows: usize,
 46        log_q: usize,
 47    ) -> GadgetCiphertextShare {
 48        GadgetCiphertextShare::new(module, log_base2k, rows, log_q)
 49    }
 50
 51    pub fn gen_share(
 52        module: &Module,
 53        sk: &SecretKey,
 54        pt: &Plaintext,
 55        seed: &[u8; 32],
 56        share: &mut GadgetCiphertextShare,
 57        tmp_bytes: &mut [u8],
 58    ) {
 59        share.seed.copy_from_slice(seed);
 60        let mut source_xe: Source = Source::new(new_seed());
 61        let mut source_xa: Source = Source::new(*seed);
 62        let mut sk_ppol: SvpPPol = module.new_svp_ppol();
 63        sk.prepare(module, &mut sk_ppol);
 64        share.value.iter_mut().for_each(|ai| {
 65            //let elem = Elem<VecZnx>{};
 66            //encrypt_rlwe_sk_thread_safe(module, ai, Some(pt.elem()), &sk_ppol, &mut source_xa, &mut source_xe, 3.2, tmp_bytes);
 67        })
 68    }
 69}
 70
 71pub struct GadgetCiphertextShare {
 72    pub seed: [u8; 32],
 73    pub log_q: usize,
 74    pub log_base2k: usize,
 75    pub value: Vec<VecZnx>,
 76}
 77
 78impl GadgetCiphertextShare {
 79    pub fn new(module: &Module, log_base2k: usize, rows: usize, log_q: usize) -> Self {
 80        let value: Vec<VecZnx> = Vec::new();
 81        let cols: usize = (log_q + log_base2k - 1) / log_base2k;
 82        (0..rows).for_each(|_| {
 83            let vec_znx: VecZnx = module.new_vec_znx(cols);
 84        });
 85        Self {
 86            seed: [u8::default(); 32],
 87            log_q: log_q,
 88            log_base2k: log_base2k,
 89            value: value,
 90        }
 91    }
 92
 93    pub fn rows(&self) -> usize {
 94        self.value.len()
 95    }
 96
 97    pub fn cols(&self) -> usize {
 98        self.value[0].cols()
 99    }
100
101    pub fn aggregate_inplace(&mut self, module: &Module, a: &GadgetCiphertextShare) {
102        izip!(self.value.iter_mut(), a.value.iter()).for_each(|(bi, ai)| {
103            module.vec_znx_add_inplace(bi, ai);
104        })
105    }
106
107    pub fn get(&self, module: &Module, b: &mut Ciphertext<VmpPMat>, tmp_bytes: &mut [u8]) {
108        assert!(is_aligned(tmp_bytes.as_ptr()));
109
110        let rows: usize = b.rows();
111        let cols: usize = b.cols();
112
113        assert!(tmp_bytes.len() >= gadget_ciphertext_share_get_tmp_bytes(module, rows, cols));
114
115        assert_eq!(self.value.len(), rows);
116        assert_eq!(self.value[0].cols(), cols);
117
118        let (tmp_bytes_vmp_prepare_row, tmp_bytes_vec_znx) =
119            tmp_bytes.split_at_mut(module.vmp_prepare_tmp_bytes(rows, cols));
120
121        let mut c: VecZnx = VecZnx::from_bytes_borrow(module.n(), cols, tmp_bytes_vec_znx);
122
123        let mut source: Source = Source::new(self.seed);
124
125        (0..self.value.len()).for_each(|row_i| {
126            module.vmp_prepare_row(
127                b.at_mut(0),
128                self.value[row_i].raw(),
129                row_i,
130                tmp_bytes_vmp_prepare_row,
131            );
132            module.fill_uniform(self.log_base2k, &mut c, cols, &mut source);
133            module.vmp_prepare_row(b.at_mut(1), c.raw(), row_i, tmp_bytes_vmp_prepare_row)
134        })
135    }
136
137    pub fn get_new(&self, module: &Module, tmp_bytes: &mut [u8]) -> Ciphertext<VmpPMat> {
138        let mut b: Ciphertext<VmpPMat> =
139            new_gadget_ciphertext(module, self.log_base2k, self.rows(), self.log_q);
140        self.get(module, &mut b, tmp_bytes);
141        b
142    }
143}
144
145pub fn gadget_ciphertext_share_get_tmp_bytes(module: &Module, rows: usize, cols: usize) -> usize {
146    module.vmp_prepare_tmp_bytes(rows, cols) + module.bytes_of_vec_znx(cols)
147}
148
149pub struct CircularCiphertextProtocol {}
150
151pub struct CircularGadgetCiphertextProtocol {}