use backend::hal::{ api::{FillUniform, Reset}, layouts::{Backend, Data, DataMut, DataRef, MatZnx, Module, ReaderFrom, WriterTo}, }; use crate::{GGLWEEncryptSkFamily, GLWESecret, GLWESecretExec, GLWESwitchingKey, Infos}; use std::fmt; /// A special [GLWESwitchingKey] required to for the conversion from [GLWECiphertext] to [LWECiphertext]. #[derive(PartialEq, Eq, Clone)] pub struct GLWEToLWESwitchingKey(pub(crate) GLWESwitchingKey); impl fmt::Debug for GLWEToLWESwitchingKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) } } impl FillUniform for GLWEToLWESwitchingKey { fn fill_uniform(&mut self, source: &mut sampling::source::Source) { self.0.fill_uniform(source); } } impl Reset for GLWEToLWESwitchingKey { fn reset(&mut self) { self.0.reset(); } } impl fmt::Display for GLWEToLWESwitchingKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "(GLWEToLWESwitchingKey) {}", self.0) } } impl Infos for GLWEToLWESwitchingKey { type Inner = MatZnx; fn inner(&self) -> &Self::Inner { &self.0.inner() } fn basek(&self) -> usize { self.0.basek() } fn k(&self) -> usize { self.0.k() } } impl GLWEToLWESwitchingKey { pub fn digits(&self) -> usize { self.0.digits() } pub fn rank(&self) -> usize { self.0.rank() } pub fn rank_in(&self) -> usize { self.0.rank_in() } pub fn rank_out(&self) -> usize { self.0.rank_out() } } impl ReaderFrom for GLWEToLWESwitchingKey { fn read_from(&mut self, reader: &mut R) -> std::io::Result<()> { self.0.read_from(reader) } } impl WriterTo for GLWEToLWESwitchingKey { fn write_to(&self, writer: &mut W) -> std::io::Result<()> { self.0.write_to(writer) } } impl GLWEToLWESwitchingKey> { pub fn alloc(n: usize, basek: usize, k: usize, rows: usize, rank_in: usize) -> Self { Self(GLWESwitchingKey::alloc(n, basek, k, rows, 1, rank_in, 1)) } pub fn encrypt_sk_scratch_space(module: &Module, n: usize, basek: usize, k: usize, rank_in: usize) -> usize where Module: GGLWEEncryptSkFamily, { GLWESecretExec::bytes_of(module, n, rank_in) + (GLWESwitchingKey::encrypt_sk_scratch_space(module, n, basek, k, rank_in, 1) | GLWESecret::bytes_of(n, rank_in)) } } #[derive(PartialEq, Eq, Clone)] pub struct LWEToGLWESwitchingKey(pub(crate) GLWESwitchingKey); impl fmt::Debug for LWEToGLWESwitchingKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) } } impl FillUniform for LWEToGLWESwitchingKey { fn fill_uniform(&mut self, source: &mut sampling::source::Source) { self.0.fill_uniform(source); } } impl Reset for LWEToGLWESwitchingKey { fn reset(&mut self) { self.0.reset(); } } impl fmt::Display for LWEToGLWESwitchingKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "(LWEToGLWESwitchingKey) {}", self.0) } } impl Infos for LWEToGLWESwitchingKey { type Inner = MatZnx; fn inner(&self) -> &Self::Inner { &self.0.inner() } fn basek(&self) -> usize { self.0.basek() } fn k(&self) -> usize { self.0.k() } } impl LWEToGLWESwitchingKey { pub fn digits(&self) -> usize { self.0.digits() } pub fn rank(&self) -> usize { self.0.rank() } pub fn rank_in(&self) -> usize { self.0.rank_in() } pub fn rank_out(&self) -> usize { self.0.rank_out() } } impl ReaderFrom for LWEToGLWESwitchingKey { fn read_from(&mut self, reader: &mut R) -> std::io::Result<()> { self.0.read_from(reader) } } impl WriterTo for LWEToGLWESwitchingKey { fn write_to(&self, writer: &mut W) -> std::io::Result<()> { self.0.write_to(writer) } } impl LWEToGLWESwitchingKey> { pub fn alloc(n: usize, basek: usize, k: usize, rows: usize, rank_out: usize) -> Self { Self(GLWESwitchingKey::alloc(n, basek, k, rows, 1, 1, rank_out)) } pub fn encrypt_sk_scratch_space(module: &Module, n: usize, basek: usize, k: usize, rank_out: usize) -> usize where Module: GGLWEEncryptSkFamily, { GLWESwitchingKey::encrypt_sk_scratch_space(module, n, basek, k, 1, rank_out) + GLWESecret::bytes_of(n, 1) } } #[derive(PartialEq, Eq, Clone)] pub struct LWESwitchingKey(pub(crate) GLWESwitchingKey); impl fmt::Debug for LWESwitchingKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self) } } impl FillUniform for LWESwitchingKey { fn fill_uniform(&mut self, source: &mut sampling::source::Source) { self.0.fill_uniform(source); } } impl Reset for LWESwitchingKey { fn reset(&mut self) { self.0.reset(); } } impl fmt::Display for LWESwitchingKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "(LWESwitchingKey) {}", self.0) } } impl Infos for LWESwitchingKey { type Inner = MatZnx; fn inner(&self) -> &Self::Inner { &self.0.inner() } fn basek(&self) -> usize { self.0.basek() } fn k(&self) -> usize { self.0.k() } } impl LWESwitchingKey { pub fn digits(&self) -> usize { self.0.digits() } pub fn rank(&self) -> usize { self.0.rank() } pub fn rank_in(&self) -> usize { self.0.rank_in() } pub fn rank_out(&self) -> usize { self.0.rank_out() } } impl ReaderFrom for LWESwitchingKey { fn read_from(&mut self, reader: &mut R) -> std::io::Result<()> { self.0.read_from(reader) } } impl WriterTo for LWESwitchingKey { fn write_to(&self, writer: &mut W) -> std::io::Result<()> { self.0.write_to(writer) } } impl LWESwitchingKey> { pub fn alloc(n: usize, basek: usize, k: usize, rows: usize) -> Self { Self(GLWESwitchingKey::alloc(n, basek, k, rows, 1, 1, 1)) } pub fn encrypt_sk_scratch_space(module: &Module, n: usize, basek: usize, k: usize) -> usize where Module: GGLWEEncryptSkFamily, { GLWESecret::bytes_of(n, 1) + GLWESecretExec::bytes_of(module, n, 1) + GLWESwitchingKey::encrypt_sk_scratch_space(module, n, basek, k, 1, 1) } }