arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-core/src/tests/test_suite/conversion.rs
poulpy-core/src/tests/test_suite/conversion.rsRaw
  1use poulpy_hal::{
  2    api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow},
  3    layouts::{Backend, Module, Scratch, ScratchOwned, ZnxView},
  4    source::Source,
  5};
  6
  7use crate::{
  8    GLWEDecrypt, GLWEEncryptSk, GLWEFromLWE, GLWEToLWESwitchingKeyEncryptSk, LWEDecrypt, LWEEncryptSk,
  9    LWEToGLWESwitchingKeyEncryptSk, ScratchTakeCore,
 10    layouts::{
 11        Base2K, Degree, Dnum, GLWE, GLWELayout, GLWEPlaintext, GLWESecret, GLWESecretPrepare, GLWESecretPreparedAlloc,
 12        GLWEToLWEKeyLayout, GLWEToLWESwitchingKey, GLWEToLWESwitchingKeyPrepare, GLWEToLWESwitchingKeyPreparedAlloc, LWE,
 13        LWELayout, LWEPlaintext, LWESecret, LWEToGLWESwitchingKey, LWEToGLWESwitchingKeyLayout, LWEToGLWESwitchingKeyPrepare,
 14        LWEToGLWESwitchingKeyPreparedAlloc, Rank, TorusPrecision,
 15        prepared::{GLWESecretPrepared, GLWEToLWESwitchingKeyPrepared, LWEToGLWESwitchingKeyPrepared},
 16    },
 17};
 18
 19pub fn test_lwe_to_glwe<BE: Backend>(module: &Module<BE>)
 20where
 21    Module<BE>: GLWEFromLWE<BE>
 22        + LWEToGLWESwitchingKeyEncryptSk<BE>
 23        + GLWEDecrypt<BE>
 24        + GLWESecretPrepare<BE>
 25        + GLWESecretPreparedAlloc<BE>
 26        + LWEEncryptSk<BE>
 27        + LWEToGLWESwitchingKeyPreparedAlloc<BE>
 28        + LWEToGLWESwitchingKeyPrepare<BE>,
 29    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
 30    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
 31{
 32    let n_glwe: Degree = Degree(module.n() as u32);
 33    let n_lwe: Degree = Degree(22);
 34
 35    let rank: Rank = Rank(2);
 36    let k_lwe_pt: TorusPrecision = TorusPrecision(8);
 37
 38    let mut source_xs: Source = Source::new([0u8; 32]);
 39    let mut source_xa: Source = Source::new([0u8; 32]);
 40    let mut source_xe: Source = Source::new([0u8; 32]);
 41
 42    let lwe_to_glwe_infos: LWEToGLWESwitchingKeyLayout = LWEToGLWESwitchingKeyLayout {
 43        n: n_glwe,
 44        base2k: Base2K(17),
 45        k: TorusPrecision(51),
 46        dnum: Dnum(2),
 47        rank_out: rank,
 48    };
 49
 50    let glwe_infos: GLWELayout = GLWELayout {
 51        n: n_glwe,
 52        base2k: Base2K(17),
 53        k: TorusPrecision(34),
 54        rank,
 55    };
 56
 57    let lwe_infos: LWELayout = LWELayout {
 58        n: n_lwe,
 59        base2k: Base2K(17),
 60        k: TorusPrecision(34),
 61    };
 62
 63    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(
 64        LWEToGLWESwitchingKey::encrypt_sk_tmp_bytes(module, &lwe_to_glwe_infos)
 65            | GLWE::from_lwe_tmp_bytes(module, &glwe_infos, &lwe_infos, &lwe_to_glwe_infos)
 66            | GLWE::decrypt_tmp_bytes(module, &glwe_infos),
 67    );
 68
 69    let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
 70    sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
 71
 72    let mut sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc_from_infos(module, &sk_glwe);
 73    sk_glwe_prepared.prepare(module, &sk_glwe);
 74
 75    let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe);
 76    sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
 77
 78    let data: i64 = 17;
 79
 80    let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc_from_infos(&lwe_infos);
 81    lwe_pt.encode_i64(data, k_lwe_pt);
 82
 83    let mut lwe_ct: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_infos);
 84    lwe_ct.encrypt_sk(module, &lwe_pt, &sk_lwe, &mut source_xa, &mut source_xe);
 85
 86    let mut ksk: LWEToGLWESwitchingKey<Vec<u8>> = LWEToGLWESwitchingKey::alloc_from_infos(&lwe_to_glwe_infos);
 87
 88    ksk.encrypt_sk(
 89        module,
 90        &sk_lwe,
 91        &sk_glwe_prepared,
 92        &mut source_xa,
 93        &mut source_xe,
 94        scratch.borrow(),
 95    );
 96
 97    let mut glwe_ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
 98
 99    let mut ksk_prepared: LWEToGLWESwitchingKeyPrepared<Vec<u8>, BE> =
100        LWEToGLWESwitchingKeyPrepared::alloc_from_infos(module, &ksk);
101    ksk_prepared.prepare(module, &ksk, scratch.borrow());
102
103    glwe_ct.from_lwe(module, &lwe_ct, &ksk_prepared, scratch.borrow());
104
105    let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
106    glwe_ct.decrypt(module, &mut glwe_pt, &sk_glwe_prepared, scratch.borrow());
107
108    assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
109}
110
111pub fn test_glwe_to_lwe<BE: Backend>(module: &Module<BE>)
112where
113    Module<BE>: GLWEFromLWE<BE>
114        + GLWEToLWESwitchingKeyEncryptSk<BE>
115        + GLWEEncryptSk<BE>
116        + LWEDecrypt<BE>
117        + GLWEDecrypt<BE>
118        + GLWESecretPrepare<BE>
119        + GLWESecretPreparedAlloc<BE>
120        + GLWEToLWESwitchingKeyEncryptSk<BE>
121        + GLWEToLWESwitchingKeyPrepare<BE>
122        + GLWEToLWESwitchingKeyPreparedAlloc<BE>,
123    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
124    Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
125{
126    let n_glwe: Degree = Degree(module.n() as u32);
127    let n_lwe: Degree = Degree(22);
128
129    let rank: Rank = Rank(2);
130    let k_lwe_pt: TorusPrecision = TorusPrecision(8);
131
132    let glwe_to_lwe_infos: GLWEToLWEKeyLayout = GLWEToLWEKeyLayout {
133        n: n_glwe,
134        base2k: Base2K(17),
135        k: TorusPrecision(51),
136        dnum: Dnum(2),
137        rank_in: rank,
138    };
139
140    let glwe_infos: GLWELayout = GLWELayout {
141        n: n_glwe,
142        base2k: Base2K(17),
143        k: TorusPrecision(34),
144        rank,
145    };
146
147    let lwe_infos: LWELayout = LWELayout {
148        n: n_lwe,
149        base2k: Base2K(17),
150        k: TorusPrecision(34),
151    };
152
153    let mut source_xs: Source = Source::new([0u8; 32]);
154    let mut source_xa: Source = Source::new([0u8; 32]);
155    let mut source_xe: Source = Source::new([0u8; 32]);
156
157    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(
158        GLWEToLWESwitchingKey::encrypt_sk_tmp_bytes(module, &glwe_to_lwe_infos)
159            | LWE::from_glwe_tmp_bytes(module, &lwe_infos, &glwe_infos, &glwe_to_lwe_infos)
160            | GLWE::decrypt_tmp_bytes(module, &glwe_infos),
161    );
162
163    let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
164    sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
165
166    let mut sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc_from_infos(module, &sk_glwe);
167    sk_glwe_prepared.prepare(module, &sk_glwe);
168
169    let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe);
170    sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
171
172    let data: i64 = 17;
173    let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
174    glwe_pt.encode_coeff_i64(data, k_lwe_pt, 0);
175
176    let mut glwe_ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
177    glwe_ct.encrypt_sk(
178        module,
179        &glwe_pt,
180        &sk_glwe_prepared,
181        &mut source_xa,
182        &mut source_xe,
183        scratch.borrow(),
184    );
185
186    let mut ksk: GLWEToLWESwitchingKey<Vec<u8>> = GLWEToLWESwitchingKey::alloc_from_infos(&glwe_to_lwe_infos);
187
188    ksk.encrypt_sk(
189        module,
190        &sk_lwe,
191        &sk_glwe,
192        &mut source_xa,
193        &mut source_xe,
194        scratch.borrow(),
195    );
196
197    let mut lwe_ct: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_infos);
198
199    let mut ksk_prepared: GLWEToLWESwitchingKeyPrepared<Vec<u8>, BE> =
200        GLWEToLWESwitchingKeyPrepared::alloc_from_infos(module, &ksk);
201    ksk_prepared.prepare(module, &ksk, scratch.borrow());
202
203    lwe_ct.from_glwe(module, &glwe_ct, &ksk_prepared, scratch.borrow());
204
205    let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc_from_infos(&lwe_infos);
206    lwe_ct.decrypt(module, &mut lwe_pt, &sk_lwe);
207
208    assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
209}