arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/src/bin_fhe/bdd_arithmetic/tests/test_suite/fheuint.rs
poulpy-schemes/src/bin_fhe/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::bin_fhe::{
 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(module, a, sk, &mut source_xa, &mut source_xe, scratch.borrow());
 42
 43        a_enc.sext(module, j, keys, scratch.borrow());
 44
 45        assert_eq!(
 46            sext(a, ((1 + j as u32) << 3) - 1),
 47            a_enc.decrypt(module, sk, scratch.borrow())
 48        );
 49    }
 50
 51    for j in 0..3 {
 52        let a: u32 = 0x4443_4241;
 53        a_enc.encrypt_sk(module, a, sk, &mut source_xa, &mut source_xe, scratch.borrow());
 54
 55        a_enc.sext(module, j, keys, scratch.borrow());
 56
 57        assert_eq!(
 58            sext(a, ((1 + j as u32) << 3) - 1),
 59            a_enc.decrypt(module, sk, scratch.borrow())
 60        );
 61    }
 62}
 63
 64pub(crate) fn sext(x: u32, bits: u32) -> u32 {
 65    let lo: u32 = x << (u32::BITS - bits) >> (u32::BITS - bits);
 66    let hi: u32 = ((x >> bits) & 1) * (0xFFFF_FFFF << bits);
 67    hi | lo
 68}
 69
 70pub fn test_fhe_uint_splice_u8<BRA: BlindRotationAlgo, BE: Backend>(test_context: &TestContext<BRA, BE>)
 71where
 72    Module<BE>: GLWEEncryptSk<BE> + GLWERotate<BE> + GLWETrace<BE> + GLWESub + GLWEAdd + GLWEDecrypt<BE>,
 73    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
 74    Scratch<BE>: ScratchTakeBDD<u32, BE>,
 75{
 76    let glwe_infos: GLWELayout = TEST_GLWE_INFOS;
 77
 78    let module: &Module<BE> = &test_context.module;
 79    let sk: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
 80    let keys: &BDDKeyPrepared<Vec<u8>, BRA, BE> = &test_context.bdd_key;
 81
 82    let mut source_xa: Source = Source::new([2u8; 32]);
 83    let mut source_xe: Source = Source::new([3u8; 32]);
 84
 85    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
 86
 87    let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
 88    let mut b_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
 89    let mut c_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
 90
 91    let a: u32 = 0xFFFFFFFF;
 92    let b: u32 = 0xAABBCCDD;
 93
 94    b_enc.encrypt_sk(module, b, sk, &mut source_xa, &mut source_xe, scratch.borrow());
 95    a_enc.encrypt_sk(module, a, sk, &mut source_xa, &mut source_xe, scratch.borrow());
 96
 97    for dst in 0..4 {
 98        for src in 0..4 {
 99            c_enc.splice_u8(module, dst, src, &a_enc, &b_enc, keys, scratch.borrow());
100
101            let rj: u32 = (dst << 3) as u32;
102            let ri: u32 = (src << 3) as u32;
103            let a_r: u32 = a.rotate_right(rj);
104            let b_r: u32 = b.rotate_right(ri);
105
106            let c_want: u32 = ((a_r & 0xFFFF_FF00) | (b_r & 0x0000_00FF)).rotate_left(rj);
107
108            assert_eq!(c_want, c_enc.decrypt(module, sk, scratch.borrow()));
109        }
110    }
111}
112
113pub fn test_fhe_uint_splice_u16<BRA: BlindRotationAlgo, BE: Backend>(test_context: &TestContext<BRA, BE>)
114where
115    Module<BE>: GLWEEncryptSk<BE> + GLWERotate<BE> + GLWETrace<BE> + GLWESub + GLWEAdd + GLWEDecrypt<BE>,
116    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
117    Scratch<BE>: ScratchTakeBDD<u32, BE>,
118{
119    let glwe_infos: GLWELayout = TEST_GLWE_INFOS;
120
121    let module: &Module<BE> = &test_context.module;
122    let sk: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
123    let keys: &BDDKeyPrepared<Vec<u8>, BRA, BE> = &test_context.bdd_key;
124
125    let mut source_xa: Source = Source::new([2u8; 32]);
126    let mut source_xe: Source = Source::new([3u8; 32]);
127
128    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
129
130    let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
131    let mut b_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
132    let mut c_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
133
134    let a: u32 = 0xFFFFFFFF;
135    let b: u32 = 0xAABBCCDD;
136
137    b_enc.encrypt_sk(module, b, sk, &mut source_xa, &mut source_xe, scratch.borrow());
138    a_enc.encrypt_sk(module, a, sk, &mut source_xa, &mut source_xe, scratch.borrow());
139
140    for dst in 0..2 {
141        for src in 0..2 {
142            c_enc.splice_u16(module, dst, src, &a_enc, &b_enc, keys, scratch.borrow());
143            let rj: u32 = (dst << 4) as u32;
144            let ri: u32 = (src << 4) as u32;
145            let a_r: u32 = a.rotate_right(rj);
146            let b_r: u32 = b.rotate_right(ri);
147            let c_want: u32 = ((a_r & 0xFFFF_0000) | (b_r & 0x0000_FFFF)).rotate_left(rj);
148            assert_eq!(c_want, c_enc.decrypt(module, sk, scratch.borrow()));
149        }
150    }
151}
152
153pub fn test_fhe_uint_get_bit_glwe<BRA: BlindRotationAlgo, BE: Backend>(test_context: &TestContext<BRA, BE>)
154where
155    Module<BE>: GLWEEncryptSk<BE> + GLWERotate<BE> + GLWETrace<BE> + GLWESub + GLWEAdd + GLWEDecrypt<BE>,
156    ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
157    Scratch<BE>: ScratchTakeBDD<u32, BE>,
158{
159    let glwe_infos: GLWELayout = TEST_GLWE_INFOS;
160
161    let module: &Module<BE> = &test_context.module;
162    let sk: &GLWESecretPrepared<Vec<u8>, BE> = &test_context.sk_glwe;
163    let keys: &BDDKeyPrepared<Vec<u8>, BRA, BE> = &test_context.bdd_key;
164
165    let mut source_xa: Source = Source::new([2u8; 32]);
166    let mut source_xe: Source = Source::new([3u8; 32]);
167
168    let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(1 << 22);
169
170    let mut a_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
171    let mut c_enc: FheUint<Vec<u8>, u32> = FheUint::<Vec<u8>, u32>::alloc_from_infos(&glwe_infos);
172
173    let a: u32 = source_xa.next_u32();
174
175    a_enc.encrypt_sk(module, a, sk, &mut source_xa, &mut source_xe, scratch.borrow());
176
177    for i in 0..32 {
178        a_enc.get_bit_glwe(module, i, &mut c_enc, keys, scratch.borrow());
179        assert_eq!(a.bit(i) as u32, c_enc.decrypt(module, sk, scratch.borrow()));
180    }
181}