arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/fheuint.rs
poulpy-schemes/src/tfhe/bdd_arithmetic/tests/test_suite/fheuint.rsRaw
  1use poulpy_core::{
  2    GLWEAdd, GLWEDecrypt, GLWEEncryptSk, GLWERotate, GLWESub, GLWETrace,
  3    layouts::{GLWELayout, GLWESecretPrepared},
  4};
  5use poulpy_hal::{
  6    api::{ScratchOwnedAlloc, ScratchOwnedBorrow},
  7    layouts::{Backend, Module, Scratch, ScratchOwned},
  8    source::Source,
  9};
 10use rand::RngCore;
 11
 12use crate::tfhe::{
 13    bdd_arithmetic::{
 14        BDDKeyPrepared, FheUint, ScratchTakeBDD, ToBits,
 15        tests::test_suite::{TEST_GLWE_INFOS, TestContext},
 16    },
 17    blind_rotation::BlindRotationAlgo,
 18};
 19
 20pub fn test_fhe_uint_sext<BRA: BlindRotationAlgo, BE: Backend>(test_context: &TestContext<BRA, BE>)
 21where
 22    Module<BE>: GLWEEncryptSk<BE> + GLWERotate<BE> + GLWETrace<BE> + GLWESub + GLWEAdd + GLWEDecrypt<BE>,
 23    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
 24    Scratch<BE>: ScratchTakeBDD<u32, BE>,
 25{
 26    let glwe_infos: GLWELayout = TEST_GLWE_INFOS;
 27
 28    let module: &Module<BE> = &test_context.module;
 29    let sk: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
 30    let keys: &BDDKeyPrepared<Vec<u8>, BRA, BE> = &test_context.bdd_key;
 31
 32    let mut source_xa: Source = Source::new([2u8; 32]);
 33    let mut source_xe: Source = Source::new([3u8; 32]);
 34
 35    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
 36
 37    let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
 38
 39    for j in 0..3 {
 40        let a: u32 = 0x8483_8281;
 41        a_enc.encrypt_sk(
 42            module,
 43            a,
 44            sk,
 45            &mut source_xa,
 46            &mut source_xe,
 47            scratch.borrow(),
 48        );
 49
 50        a_enc.sext(module, j, keys, scratch.borrow());
 51
 52        // println!("{:08x} -> {:08x} {:08x}", a, sext(a, j), a_enc.decrypt(module, sk, scratch.borrow()));
 53
 54        assert_eq!(
 55            sext(a, ((1 + j as u32) << 3) - 1),
 56            a_enc.decrypt(module, sk, scratch.borrow())
 57        );
 58    }
 59
 60    for j in 0..3 {
 61        let a: u32 = 0x4443_4241;
 62        a_enc.encrypt_sk(
 63            module,
 64            a,
 65            sk,
 66            &mut source_xa,
 67            &mut source_xe,
 68            scratch.borrow(),
 69        );
 70
 71        a_enc.sext(module, j, keys, scratch.borrow());
 72
 73        // println!("{:08x} -> {:08x} {:08x}", a, sext(a, j), a_enc.decrypt(module, sk, scratch.borrow()));
 74
 75        assert_eq!(
 76            sext(a, ((1 + j as u32) << 3) - 1),
 77            a_enc.decrypt(module, sk, scratch.borrow())
 78        );
 79    }
 80}
 81
 82pub(crate) fn sext(x: u32, bits: u32) -> u32 {
 83    let lo: u32 = x << (u32::BITS - bits) >> (u32::BITS - bits);
 84    let hi: u32 = ((x >> bits) & 1) * (0xFFFF_FFFF << bits);
 85    hi | lo
 86}
 87
 88pub fn test_fhe_uint_splice_u8<BRA: BlindRotationAlgo, BE: Backend>(test_context: &TestContext<BRA, BE>)
 89where
 90    Module<BE>: GLWEEncryptSk<BE> + GLWERotate<BE> + GLWETrace<BE> + GLWESub + GLWEAdd + GLWEDecrypt<BE>,
 91    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
 92    Scratch<BE>: ScratchTakeBDD<u32, BE>,
 93{
 94    let glwe_infos: GLWELayout = TEST_GLWE_INFOS;
 95
 96    let module: &Module<BE> = &test_context.module;
 97    let sk: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
 98    let keys: &BDDKeyPrepared<Vec<u8>, BRA, BE> = &test_context.bdd_key;
 99
100    let mut source_xa: Source = Source::new([2u8; 32]);
101    let mut source_xe: Source = Source::new([3u8; 32]);
102
103    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
104
105    let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
106    let mut b_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
107    let mut c_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
108
109    let a: u32 = 0xFFFFFFFF;
110    let b: u32 = 0xAABBCCDD;
111
112    b_enc.encrypt_sk(
113        module,
114        b,
115        sk,
116        &mut source_xa,
117        &mut source_xe,
118        scratch.borrow(),
119    );
120    a_enc.encrypt_sk(
121        module,
122        a,
123        sk,
124        &mut source_xa,
125        &mut source_xe,
126        scratch.borrow(),
127    );
128
129    for dst in 0..4 {
130        for src in 0..4 {
131            c_enc.splice_u8(module, dst, src, &a_enc, &b_enc, keys, scratch.borrow());
132
133            let rj: u32 = (dst << 3) as u32;
134            let ri: u32 = (src << 3) as u32;
135            let a_r: u32 = a.rotate_right(rj);
136            let b_r: u32 = b.rotate_right(ri);
137
138            let c_want: u32 = ((a_r & 0xFFFF_FF00) | (b_r & 0x0000_00FF)).rotate_left(rj);
139
140            assert_eq!(c_want, c_enc.decrypt(module, sk, scratch.borrow()));
141        }
142    }
143}
144
145pub fn test_fhe_uint_splice_u16<BRA: BlindRotationAlgo, BE: Backend>(test_context: &TestContext<BRA, BE>)
146where
147    Module<BE>: GLWEEncryptSk<BE> + GLWERotate<BE> + GLWETrace<BE> + GLWESub + GLWEAdd + GLWEDecrypt<BE>,
148    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
149    Scratch<BE>: ScratchTakeBDD<u32, BE>,
150{
151    let glwe_infos: GLWELayout = TEST_GLWE_INFOS;
152
153    let module: &Module<BE> = &test_context.module;
154    let sk: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
155    let keys: &BDDKeyPrepared<Vec<u8>, BRA, BE> = &test_context.bdd_key;
156
157    let mut source_xa: Source = Source::new([2u8; 32]);
158    let mut source_xe: Source = Source::new([3u8; 32]);
159
160    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
161
162    let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
163    let mut b_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
164    let mut c_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
165
166    let a: u32 = 0xFFFFFFFF;
167    let b: u32 = 0xAABBCCDD;
168
169    b_enc.encrypt_sk(
170        module,
171        b,
172        sk,
173        &mut source_xa,
174        &mut source_xe,
175        scratch.borrow(),
176    );
177    a_enc.encrypt_sk(
178        module,
179        a,
180        sk,
181        &mut source_xa,
182        &mut source_xe,
183        scratch.borrow(),
184    );
185
186    for dst in 0..2 {
187        for src in 0..2 {
188            c_enc.splice_u16(module, dst, src, &a_enc, &b_enc, keys, scratch.borrow());
189            let rj: u32 = (dst << 4) as u32;
190            let ri: u32 = (src << 4) as u32;
191            let a_r: u32 = a.rotate_right(rj);
192            let b_r: u32 = b.rotate_right(ri);
193            let c_want: u32 = ((a_r & 0xFFFF_0000) | (b_r & 0x0000_FFFF)).rotate_left(rj);
194            assert_eq!(c_want, c_enc.decrypt(module, sk, scratch.borrow()));
195        }
196    }
197}
198
199pub fn test_fhe_uint_get_bit_glwe<BRA: BlindRotationAlgo, BE: Backend>(test_context: &TestContext<BRA, BE>)
200where
201    Module<BE>: GLWEEncryptSk<BE> + GLWERotate<BE> + GLWETrace<BE> + GLWESub + GLWEAdd + GLWEDecrypt<BE>,
202    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
203    Scratch<BE>: ScratchTakeBDD<u32, BE>,
204{
205    let glwe_infos: GLWELayout = TEST_GLWE_INFOS;
206
207    let module: &Module<BE> = &test_context.module;
208    let sk: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
209    let keys: &BDDKeyPrepared<Vec<u8>, BRA, BE> = &test_context.bdd_key;
210
211    let mut source_xa: Source = Source::new([2u8; 32]);
212    let mut source_xe: Source = Source::new([3u8; 32]);
213
214    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
215
216    let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
217    let mut c_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
218
219    let a: u32 = source_xa.next_u32();
220
221    a_enc.encrypt_sk(
222        module,
223        a,
224        sk,
225        &mut source_xa,
226        &mut source_xe,
227        scratch.borrow(),
228    );
229
230    for i in 0..32 {
231        a_enc.get_bit_glwe(module, i, &mut c_enc, keys, scratch.borrow());
232        assert_eq!(a.bit(i) as u32, c_enc.decrypt(module, sk, scratch.borrow()));
233    }
234}