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}