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}