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