arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/glwe/secret.rs
core/src/glwe/secret.rsRaw
  1use backend::hal::{
  2    api::{SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare, ZnxInfos, ZnxZero},
  3    layouts::{Backend, Data, DataMut, DataRef, Module, ReaderFrom, ScalarZnx, SvpPPol, WriterTo},
  4};
  5use sampling::source::Source;
  6
  7use crate::dist::Distribution;
  8
  9pub trait GLWESecretFamily<B: Backend> = SvpPrepare<B> + SvpPPolAllocBytes + SvpPPolAlloc<B>;
 10
 11#[derive(PartialEq, Eq, Clone)]
 12pub struct GLWESecret<D: Data> {
 13    pub(crate) data: ScalarZnx<D>,
 14    pub(crate) dist: Distribution,
 15}
 16
 17impl GLWESecret<Vec<u8>> {
 18    pub fn alloc(n: usize, rank: usize) -> Self {
 19        Self {
 20            data: ScalarZnx::alloc(n, rank),
 21            dist: Distribution::NONE,
 22        }
 23    }
 24
 25    pub fn bytes_of(n: usize, rank: usize) -> usize {
 26        ScalarZnx::alloc_bytes(n, rank)
 27    }
 28}
 29
 30impl<D: Data> GLWESecret<D> {
 31    pub fn n(&self) -> usize {
 32        self.data.n()
 33    }
 34
 35    pub fn log_n(&self) -> usize {
 36        self.data.log_n()
 37    }
 38
 39    pub fn rank(&self) -> usize {
 40        self.data.cols()
 41    }
 42}
 43
 44impl<D: DataMut> GLWESecret<D> {
 45    pub fn fill_ternary_prob(&mut self, prob: f64, source: &mut Source) {
 46        (0..self.rank()).for_each(|i| {
 47            self.data.fill_ternary_prob(i, prob, source);
 48        });
 49        self.dist = Distribution::TernaryProb(prob);
 50    }
 51
 52    pub fn fill_ternary_hw(&mut self, hw: usize, source: &mut Source) {
 53        (0..self.rank()).for_each(|i| {
 54            self.data.fill_ternary_hw(i, hw, source);
 55        });
 56        self.dist = Distribution::TernaryFixed(hw);
 57    }
 58
 59    pub fn fill_binary_prob(&mut self, prob: f64, source: &mut Source) {
 60        (0..self.rank()).for_each(|i| {
 61            self.data.fill_binary_prob(i, prob, source);
 62        });
 63        self.dist = Distribution::BinaryProb(prob);
 64    }
 65
 66    pub fn fill_binary_hw(&mut self, hw: usize, source: &mut Source) {
 67        (0..self.rank()).for_each(|i| {
 68            self.data.fill_binary_hw(i, hw, source);
 69        });
 70        self.dist = Distribution::BinaryFixed(hw);
 71    }
 72
 73    pub fn fill_binary_block(&mut self, block_size: usize, source: &mut Source) {
 74        (0..self.rank()).for_each(|i| {
 75            self.data.fill_binary_block(i, block_size, source);
 76        });
 77        self.dist = Distribution::BinaryBlock(block_size);
 78    }
 79
 80    pub fn fill_zero(&mut self) {
 81        self.data.zero();
 82        self.dist = Distribution::ZERO;
 83    }
 84}
 85
 86impl<D: DataMut> ReaderFrom for GLWESecret<D> {
 87    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
 88        match Distribution::read_from(reader) {
 89            Ok(dist) => self.dist = dist,
 90            Err(e) => return Err(e),
 91        }
 92        self.data.read_from(reader)
 93    }
 94}
 95
 96impl<D: DataRef> WriterTo for GLWESecret<D> {
 97    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
 98        match self.dist.write_to(writer) {
 99            Ok(()) => {}
100            Err(e) => return Err(e),
101        }
102        self.data.write_to(writer)
103    }
104}
105
106pub struct GLWESecretExec<D: Data, B: Backend> {
107    pub(crate) data: SvpPPol<D, B>,
108    pub(crate) dist: Distribution,
109}
110
111impl<B: Backend> GLWESecretExec<Vec<u8>, B> {
112    pub fn alloc(module: &Module<B>, n: usize, rank: usize) -> Self
113    where
114        Module<B>: SvpPPolAlloc<B>,
115    {
116        Self {
117            data: module.svp_ppol_alloc(n, rank),
118            dist: Distribution::NONE,
119        }
120    }
121
122    pub fn bytes_of(module: &Module<B>, n: usize, rank: usize) -> usize
123    where
124        Module<B>: SvpPPolAllocBytes,
125    {
126        module.svp_ppol_alloc_bytes(n, rank)
127    }
128}
129
130impl<B: Backend> GLWESecretExec<Vec<u8>, B> {
131    pub fn from<D>(module: &Module<B>, sk: &GLWESecret<D>) -> Self
132    where
133        D: DataRef,
134        Module<B>: SvpPrepare<B> + SvpPPolAlloc<B>,
135    {
136        let mut sk_dft: GLWESecretExec<Vec<u8>, B> = Self::alloc(module, sk.n(), sk.rank());
137        sk_dft.prepare(module, sk);
138        sk_dft
139    }
140}
141
142impl<D: Data, B: Backend> GLWESecretExec<D, B> {
143    pub fn n(&self) -> usize {
144        self.data.n()
145    }
146
147    pub fn log_n(&self) -> usize {
148        self.data.log_n()
149    }
150
151    pub fn rank(&self) -> usize {
152        self.data.cols()
153    }
154}
155
156impl<D: DataMut, B: Backend> GLWESecretExec<D, B> {
157    pub(crate) fn prepare<O>(&mut self, module: &Module<B>, sk: &GLWESecret<O>)
158    where
159        O: DataRef,
160        Module<B>: SvpPrepare<B>,
161    {
162        (0..self.rank()).for_each(|i| {
163            module.svp_prepare(&mut self.data, i, &sk.data, i);
164        });
165        self.dist = sk.dist
166    }
167}