refactor(all): refactor oprf integer and hl APIs

This commit is contained in:
Mayeul@Zama
2024-08-01 18:19:44 +02:00
committed by mayeul-zama
parent 2a4026c761
commit 93ff6992e2
7 changed files with 310 additions and 122 deletions

View File

@@ -19,11 +19,13 @@ pub fn unsigned_oprf(c: &mut Criterion) {
let bench_id = format!("{}::{}::{}_bits", bench_name, param.name(), bit_size);
bench_group.bench_function(&bench_id, |b| {
b.iter(|| {
_ = black_box(sk.par_generate_oblivious_pseudo_random_unsigned_integer(
Seed(0),
bit_size as u64,
num_block as u64,
));
_ = black_box(
sk.par_generate_oblivious_pseudo_random_unsigned_integer_bounded(
Seed(0),
bit_size as u64,
num_block as u64,
),
);
})
});

View File

@@ -599,7 +599,7 @@ void test_oprf(const ClientKey *client_key) {
fhe_uint8_destroy(ct);
status = generate_oblivious_pseudo_random_bits_fhe_uint8(&ct, 0, 0, 2);
status = generate_oblivious_pseudo_random_bounded_fhe_uint8(&ct, 0, 0, 2);
assert(status == 0);
status = fhe_uint8_decrypt(ct, client_key, &decrypted);
@@ -613,7 +613,7 @@ void test_oprf(const ClientKey *client_key) {
{
FheInt8 *ct = NULL;
int status = generate_oblivious_pseudo_random_full_signed_range_fhe_int8(&ct, 0, 0);
int status = generate_oblivious_pseudo_random_fhe_int8(&ct, 0, 0);
assert(status == 0);
int8_t decrypted;
@@ -623,7 +623,7 @@ void test_oprf(const ClientKey *client_key) {
fhe_int8_destroy(ct);
status = generate_oblivious_pseudo_random_unsigned_fhe_int8(&ct, 0, 0, 2);
status = generate_oblivious_pseudo_random_bounded_fhe_int8(&ct, 0, 0, 2);
assert(status == 0);
status = fhe_int8_decrypt(ct, client_key, &decrypted);

View File

@@ -1,10 +1,24 @@
# Generate encrypted pseudo random values
This document gives an example of generating pseudo random values in FHE that are not known by the server.
This document explains the mechanism and steps to generate an oblivious encrypted random value using only server keys.
The goal is to give to the server the possibility to generate a random value, which will be obtained in an encrypted format and will remain unknown to the server. The implementation is based on [this article](https://eprint.iacr.org/2024/665).
This is possible through two methods on `FheUint` and `FheInt`:
- `generate_oblivious_pseudo_random` which return an integer taken uniformly in the full integer range (`[0; 2^N[` for a `FheUintN` and `[-2^(N-1); 2^(N-1)[` for a `FheIntN`).
- `generate_oblivious_pseudo_random_bounded` which return an integer taken uniformly in `[0; 2^random_bits_count[`. For a `FheUintN`, we must have `random_bits_count <= N`. For a `FheIntN`, we must have `random_bits_count <= N - 1`.
Both methods functions take a seed `Seed` as input, which could be any `u128` value.
They both rely on the use of the usual server key.
The output is reproducible, i.e., the function is deterministic from the inputs: assuming the same hardware, seed and server key, this function outputs the same random encrypted value.
Here is an example of the usage:
```rust
use tfhe::prelude::FheDecrypt;
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8, Seed};
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8, FheInt8, Seed};
pub fn main() {
let config = ConfigBuilder::default().build();
@@ -14,12 +28,22 @@ pub fn main() {
let random_bits_count = 3;
// You can pass a 128 bits Seed here
// The generated values will always be the same for a given server key
// The server cannot know what value was generated
let ct_res = FheUint8::generate_oblivious_pseudo_random(Seed(0), random_bits_count);
let ct_res = FheUint8::generate_oblivious_pseudo_random(Seed(0));
let dec_result: u8 = ct_res.decrypt(&client_key);
let ct_res = FheUint8::generate_oblivious_pseudo_random_bounded(Seed(0), random_bits_count);
let dec_result: u8 = ct_res.decrypt(&client_key);
assert!(dec_result < (1 << random_bits_count));
let ct_res = FheInt8::generate_oblivious_pseudo_random(Seed(0));
let dec_result: i8 = ct_res.decrypt(&client_key);
let ct_res = FheInt8::generate_oblivious_pseudo_random_bounded(Seed(0), random_bits_count);
let dec_result: i8 = ct_res.decrypt(&client_key);
assert!(dec_result < (1 << random_bits_count));
}
```

View File

@@ -491,7 +491,6 @@ macro_rules! impl_oprf_for_uint {
seed_low_bytes: u64,
seed_high_bytes: u64,
) -> c_int {
use crate::high_level_api::IntegerId;
$crate::c_api::utils::catch_panic(|| {
let seed_low_bytes: u128 = seed_low_bytes.into();
let seed_high_bytes: u128 = seed_high_bytes.into();
@@ -499,7 +498,6 @@ macro_rules! impl_oprf_for_uint {
let result = crate::FheUint::generate_oblivious_pseudo_random(
seed,
<crate::[<$name Id>] as IntegerId>::num_bits() as u64
);
*out_result = Box::into_raw(Box::new($name(result)));
})
@@ -508,7 +506,7 @@ macro_rules! impl_oprf_for_uint {
::paste::paste! {
#[no_mangle]
pub unsafe extern "C" fn [<generate_oblivious_pseudo_random_bits_ $name:snake>](
pub unsafe extern "C" fn [<generate_oblivious_pseudo_random_bounded_ $name:snake>](
out_result: *mut *mut $name,
seed_low_bytes: u64,
seed_high_bytes: u64,
@@ -520,7 +518,7 @@ macro_rules! impl_oprf_for_uint {
let seed_high_bytes: u128 = seed_high_bytes.into();
let seed = crate::Seed((seed_high_bytes << 64) | seed_low_bytes);
let result = crate::FheUint::generate_oblivious_pseudo_random(seed, random_bits_count);
let result = crate::FheUint::generate_oblivious_pseudo_random_bounded(seed, random_bits_count);
*out_result = Box::into_raw(Box::new($name(result)));
})
}
@@ -532,35 +530,9 @@ macro_rules! impl_oprf_for_int {
(
name: $name:ident
) => {
::paste::paste! {
#[no_mangle]
pub unsafe extern "C" fn [<generate_oblivious_pseudo_random_unsigned_ $name:snake>](
out_result: *mut *mut $name,
seed_low_bytes: u64,
seed_high_bytes: u64,
random_bits_count: u64,
) -> c_int {
$crate::c_api::utils::catch_panic(|| {
let seed_low_bytes: u128 = seed_low_bytes.into();
let seed_high_bytes: u128 = seed_high_bytes.into();
let seed = crate::Seed((seed_high_bytes << 64) | seed_low_bytes);
let result =
crate::FheInt::generate_oblivious_pseudo_random(
seed,
crate::high_level_api::SignedRandomizationSpec::Unsigned {
random_bits_count
},
);
*out_result = Box::into_raw(Box::new($name(result)));
})
}
}
::paste::paste! {
#[no_mangle]
pub unsafe extern "C" fn [<generate_oblivious_pseudo_random_full_signed_range_ $name:snake>](
pub unsafe extern "C" fn [<generate_oblivious_pseudo_random_ $name:snake>](
out_result: *mut *mut $name,
seed_low_bytes: u64,
seed_high_bytes: u64,
@@ -572,12 +544,34 @@ macro_rules! impl_oprf_for_int {
let result = crate::FheInt::generate_oblivious_pseudo_random(
seed,
crate::high_level_api::SignedRandomizationSpec::FullSigned,
);
*out_result = Box::into_raw(Box::new($name(result)));
})
}
}
::paste::paste! {
#[no_mangle]
pub unsafe extern "C" fn [<generate_oblivious_pseudo_random_bounded_ $name:snake>](
out_result: *mut *mut $name,
seed_low_bytes: u64,
seed_high_bytes: u64,
random_bits_count: u64,
) -> c_int {
$crate::c_api::utils::catch_panic(|| {
let seed_low_bytes: u128 = seed_low_bytes.into();
let seed_high_bytes: u128 = seed_high_bytes.into();
let seed = crate::Seed((seed_high_bytes << 64) | seed_low_bytes);
let result =
crate::FheInt::generate_oblivious_pseudo_random_bounded(
seed,
random_bits_count,
);
*out_result = Box::into_raw(Box::new($name(result)));
})
}
}
};
}

View File

@@ -1,14 +1,49 @@
use super::{FheIntId, FheUintId};
use crate::high_level_api::global_state;
use crate::high_level_api::keys::InternalServerKey;
use crate::integer::oprf::SignedRandomizationSpec;
use crate::{FheInt, FheUint, Seed};
impl<Id: FheUintId> FheUint<Id> {
/// Generates an encrypted unsigned integer
/// taken uniformly in its full range using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::prelude::FheDecrypt;
/// use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8, Seed};
///
/// let config = ConfigBuilder::default().build();
/// let (client_key, server_key) = generate_keys(config);
///
/// set_server_key(server_key);
///
/// let ct_res = FheUint8::generate_oblivious_pseudo_random(Seed(0));
///
/// let dec_result: u16 = ct_res.decrypt(&client_key);
/// ```
pub fn generate_oblivious_pseudo_random(seed: Seed) -> Self {
global_state::with_internal_keys(|key| match key {
InternalServerKey::Cpu(key) => {
let ct = key
.pbs_key()
.par_generate_oblivious_pseudo_random_unsigned_integer(
seed,
Id::num_blocks(key.message_modulus()) as u64,
);
Self::new(ct, key.tag.clone())
}
#[cfg(feature = "gpu")]
InternalServerKey::Cuda(_) => {
todo!("Cuda devices do not yet support oblivious pseudo random generation")
}
})
}
/// Generates an encrypted `num_block` blocks unsigned integer
/// taken uniformly in `[0, 2^random_bits_count[` using the given seed
/// The encryted value is oblivious to the server
/// It can be useful to make server random generation deterministic
/// taken uniformly in `[0, 2^random_bits_count[` using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::prelude::FheDecrypt;
@@ -21,17 +56,17 @@ impl<Id: FheUintId> FheUint<Id> {
///
/// let random_bits_count = 3;
///
/// let ct_res = FheUint8::generate_oblivious_pseudo_random(Seed(0), random_bits_count);
/// let ct_res = FheUint8::generate_oblivious_pseudo_random_bounded(Seed(0), random_bits_count);
///
/// let dec_result: u16 = ct_res.decrypt(&client_key);
/// assert!(dec_result < (1 << random_bits_count));
/// ```
pub fn generate_oblivious_pseudo_random(seed: Seed, random_bits_count: u64) -> Self {
pub fn generate_oblivious_pseudo_random_bounded(seed: Seed, random_bits_count: u64) -> Self {
global_state::with_internal_keys(|key| match key {
InternalServerKey::Cpu(key) => {
let ct = key
.pbs_key()
.par_generate_oblivious_pseudo_random_unsigned_integer(
.par_generate_oblivious_pseudo_random_unsigned_integer_bounded(
seed,
random_bits_count,
Id::num_blocks(key.message_modulus()) as u64,
@@ -48,40 +83,33 @@ impl<Id: FheUintId> FheUint<Id> {
}
impl<Id: FheIntId> FheInt<Id> {
/// Generates an encrypted `num_block` blocks signed integer
/// using the given seed following the randomizer spec
/// The encryted value is oblivious to the server
/// It can be useful to make server random generation deterministic
/// Generates an encrypted signed integer
/// taken uniformly in its full range using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::prelude::FheDecrypt;
/// use tfhe::{
/// generate_keys, set_server_key, ConfigBuilder, FheInt8, Seed, SignedRandomizationSpec,
/// };
/// use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheInt8, Seed};
///
/// let config = ConfigBuilder::default().build();
/// let (client_key, server_key) = generate_keys(config);
///
/// set_server_key(server_key);
///
/// let ct_res =
/// FheInt8::generate_oblivious_pseudo_random(Seed(0), SignedRandomizationSpec::FullSigned);
/// let ct_res = FheInt8::generate_oblivious_pseudo_random(Seed(0));
///
/// let dec_result: i16 = ct_res.decrypt(&client_key);
/// assert!(dec_result < 1 << 7);
/// assert!(dec_result >= -(1 << 7));
/// ```
pub fn generate_oblivious_pseudo_random(
seed: Seed,
randomizer: SignedRandomizationSpec,
) -> Self {
pub fn generate_oblivious_pseudo_random(seed: Seed) -> Self {
global_state::with_internal_keys(|key| match key {
InternalServerKey::Cpu(key) => {
let ct = key
.pbs_key()
.par_generate_oblivious_pseudo_random_signed_integer(
seed,
randomizer,
Id::num_blocks(key.message_modulus()) as u64,
);
Self::new(ct, key.tag.clone())
@@ -92,4 +120,46 @@ impl<Id: FheIntId> FheInt<Id> {
}
})
}
/// Generates an encrypted `num_block` blocks signed integer
/// taken uniformly in `[0, 2^random_bits_count[` using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::prelude::FheDecrypt;
/// use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheInt8, Seed};
///
/// let config = ConfigBuilder::default().build();
/// let (client_key, server_key) = generate_keys(config);
///
/// set_server_key(server_key);
///
/// let random_bits_count = 3;
///
/// let ct_res = FheInt8::generate_oblivious_pseudo_random_bounded(Seed(0), random_bits_count);
///
/// let dec_result: i16 = ct_res.decrypt(&client_key);
/// assert!(dec_result >= 0);
/// assert!(dec_result < 1 << random_bits_count);
/// ```
pub fn generate_oblivious_pseudo_random_bounded(seed: Seed, random_bits_count: u64) -> Self {
global_state::with_internal_keys(|key| match key {
InternalServerKey::Cpu(key) => {
let ct = key
.pbs_key()
.par_generate_oblivious_pseudo_random_signed_integer_bounded(
seed,
random_bits_count,
Id::num_blocks(key.message_modulus()) as u64,
);
Self::new(ct, key.tag.clone())
}
#[cfg(feature = "gpu")]
InternalServerKey::Cuda(_) => {
todo!("Cuda devices do not yet support oblivious pseudo random generation")
}
})
}
}

View File

@@ -24,7 +24,6 @@ macro_rules! expand_pub_use_fhe_type(
);
pub use crate::core_crypto::commons::math::random::Seed;
pub use crate::integer::oprf::SignedRandomizationSpec;
pub use crate::integer::server_key::MatchValues;
pub use config::{Config, ConfigBuilder};
pub use global_state::{set_server_key, unset_server_key, with_server_key_as_context};

View File

@@ -7,9 +7,79 @@ pub use concrete_csprng::seeders::{Seed, Seeder};
impl ServerKey {
/// Generates an encrypted `num_block` blocks unsigned integer
/// taken uniformly in `[0, 2^random_bits_count[` using the given seed
/// The encryted value is oblivious to the server
/// It can be useful to make server random generation deterministic
/// taken uniformly in its full range using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::integer::gen_keys_radix;
/// use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
/// use tfhe::Seed;
///
/// let size = 4;
///
/// // Generate the client key and the server key:
/// let (cks, sks) = gen_keys_radix(PARAM_MESSAGE_2_CARRY_2_KS_PBS, size);
///
/// let ct_res = sks.par_generate_oblivious_pseudo_random_unsigned_integer(Seed(0), size as u64);
///
/// // Decrypt:
/// let dec_result: u64 = cks.decrypt(&ct_res);
///
/// assert!(dec_result < 1 << (2 * size));
/// ```
pub fn par_generate_oblivious_pseudo_random_unsigned_integer(
&self,
seed: Seed,
num_blocks: u64,
) -> RadixCiphertext {
assert!(self.message_modulus().0.is_power_of_two());
let range_log_size = self.message_modulus().0.ilog2() as u64 * num_blocks;
let random_bits_count = range_log_size;
assert!(self.message_modulus().0.is_power_of_two());
let message_bits_count = self.message_modulus().0.ilog2() as u64;
let mut deterministic_seeder = DeterministicSeeder::<ActivatedRandomGenerator>::new(seed);
let seeds: Vec<Seed> = (0..num_blocks)
.map(|_| deterministic_seeder.seed())
.collect();
let blocks = seeds
.into_par_iter()
.enumerate()
.map(|(i, seed)| {
let i = i as u64;
if i * message_bits_count < random_bits_count {
// if we generate 5 bits of noise in n blocks of 2 bits, the third (i=2) block
// must have only one bit of random
if random_bits_count < (i + 1) * message_bits_count {
let top_message_bits_count = random_bits_count - i * message_bits_count;
assert!(top_message_bits_count <= message_bits_count);
self.key
.generate_oblivious_pseudo_random(seed, top_message_bits_count)
} else {
self.key
.generate_oblivious_pseudo_random(seed, message_bits_count)
}
} else {
self.key.create_trivial(0)
}
})
.collect::<Vec<_>>();
RadixCiphertext::from(blocks)
}
/// Generates an encrypted `num_block` blocks unsigned integer
/// taken uniformly in `[0, 2^random_bits_count[` using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::integer::gen_keys_radix;
@@ -23,7 +93,7 @@ impl ServerKey {
///
/// let random_bits_count = 3;
///
/// let ct_res = sks.par_generate_oblivious_pseudo_random_unsigned_integer(
/// let ct_res = sks.par_generate_oblivious_pseudo_random_unsigned_integer_bounded(
/// Seed(0),
/// random_bits_count,
/// size as u64,
@@ -33,7 +103,7 @@ impl ServerKey {
/// let dec_result: u64 = cks.decrypt(&ct_res);
/// assert!(dec_result < (1 << random_bits_count));
/// ```
pub fn par_generate_oblivious_pseudo_random_unsigned_integer(
pub fn par_generate_oblivious_pseudo_random_unsigned_integer_bounded(
&self,
seed: Seed,
random_bits_count: u64,
@@ -86,24 +156,14 @@ impl ServerKey {
}
}
// Describes in which range a random signed integer should be generated
#[derive(Copy, Clone)]
pub enum SignedRandomizationSpec {
// taken uniformly in `[0, 2^random_bits_count[`
Unsigned { random_bits_count: u64 },
// taken uniformly in the full range [-2^(p-1), 2^(p-1)[
FullSigned,
}
impl ServerKey {
/// Generates an encrypted `num_block` blocks signed integer
/// using the given seed following the randomizer spec
/// The encryted value is oblivious to the server
/// It can be useful to make server random generation deterministic
/// taken uniformly in its full range using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::integer::gen_keys_radix;
/// use tfhe::integer::oprf::SignedRandomizationSpec;
/// use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
/// use tfhe::Seed;
///
@@ -112,11 +172,7 @@ impl ServerKey {
/// // Generate the client key and the server key:
/// let (cks, sks) = gen_keys_radix(PARAM_MESSAGE_2_CARRY_2_KS_PBS, size);
///
/// let ct_res = sks.par_generate_oblivious_pseudo_random_signed_integer(
/// Seed(0),
/// SignedRandomizationSpec::FullSigned,
/// size as u64,
/// );
/// let ct_res = sks.par_generate_oblivious_pseudo_random_signed_integer(Seed(0), size as u64);
///
/// // Decrypt:
/// let dec_result: i64 = cks.decrypt_signed(&ct_res);
@@ -126,14 +182,67 @@ impl ServerKey {
pub fn par_generate_oblivious_pseudo_random_signed_integer(
&self,
seed: Seed,
randomizer: SignedRandomizationSpec,
num_blocks: u64,
) -> SignedRadixCiphertext {
#[allow(clippy::int_plus_one)]
if let SignedRandomizationSpec::Unsigned { random_bits_count } = randomizer {
assert!(self.message_modulus().0.is_power_of_two());
let range_log_size = self.message_modulus().0.ilog2() as u64 * num_blocks;
assert!(self.message_modulus().0.is_power_of_two());
let message_bits_count = self.message_modulus().0.ilog2() as u64;
let mut deterministic_seeder = DeterministicSeeder::<ActivatedRandomGenerator>::new(seed);
let seeds: Vec<Seed> = (0..num_blocks)
.map(|_| deterministic_seeder.seed())
.collect();
let blocks = seeds
.into_par_iter()
.map(|seed| {
self.key
.generate_oblivious_pseudo_random(seed, message_bits_count)
})
.collect::<Vec<_>>();
SignedRadixCiphertext::from(blocks)
}
/// Generates an encrypted `num_block` blocks signed integer
/// taken uniformly in `[0, 2^random_bits_count[` using the given seed.
/// The encryted value is oblivious to the server.
/// It can be useful to make server random generation deterministic.
///
/// ```rust
/// use tfhe::integer::gen_keys_radix;
/// use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
/// use tfhe::Seed;
///
/// let size = 4;
///
/// let random_bits_count = 3;
///
/// // Generate the client key and the server key:
/// let (cks, sks) = gen_keys_radix(PARAM_MESSAGE_2_CARRY_2_KS_PBS, size);
///
/// let ct_res = sks.par_generate_oblivious_pseudo_random_signed_integer_bounded(
/// Seed(0),
/// random_bits_count,
/// size as u64,
/// );
///
/// // Decrypt:
/// let dec_result: i64 = cks.decrypt_signed(&ct_res);
/// assert!(dec_result >= 0);
/// assert!(dec_result < (1 << random_bits_count));
/// ```
pub fn par_generate_oblivious_pseudo_random_signed_integer_bounded(
&self,
seed: Seed,
random_bits_count: u64,
num_blocks: u64,
) -> SignedRadixCiphertext {
assert!(self.message_modulus().0.is_power_of_two());
let range_log_size = self.message_modulus().0.ilog2() as u64 * num_blocks;
#[allow(clippy::int_plus_one)]
{
assert!(
random_bits_count + 1 <= range_log_size,
"The range asked for a random value (=[0, 2^{}[) does not fit in the available range [-2^{}, 2^{}[",
@@ -156,30 +265,22 @@ impl ServerKey {
.map(|(i, seed)| {
let i = i as u64;
match randomizer {
SignedRandomizationSpec::Unsigned { random_bits_count } => {
if i * message_bits_count < random_bits_count {
// if we generate 5 bits of noise in n blocks of 2 bits, the third (i=2)
// block must have only one bit of random
if random_bits_count < (i + 1) * message_bits_count {
let top_message_bits_count =
random_bits_count - i * message_bits_count;
if i * message_bits_count < random_bits_count {
// if we generate 5 bits of noise in n blocks of 2 bits, the third (i=2)
// block must have only one bit of random
if random_bits_count < (i + 1) * message_bits_count {
let top_message_bits_count = random_bits_count - i * message_bits_count;
assert!(top_message_bits_count <= message_bits_count);
assert!(top_message_bits_count <= message_bits_count);
self.key
.generate_oblivious_pseudo_random(seed, top_message_bits_count)
} else {
self.key
.generate_oblivious_pseudo_random(seed, message_bits_count)
}
} else {
self.key.create_trivial(0)
}
self.key
.generate_oblivious_pseudo_random(seed, top_message_bits_count)
} else {
self.key
.generate_oblivious_pseudo_random(seed, message_bits_count)
}
SignedRandomizationSpec::FullSigned => self
.key
.generate_oblivious_pseudo_random(seed, message_bits_count),
} else {
self.key.create_trivial(0)
}
})
.collect::<Vec<_>>();
@@ -191,7 +292,6 @@ impl ServerKey {
#[cfg(test)]
pub(crate) mod test {
use crate::integer::oprf::SignedRandomizationSpec;
use crate::shortint::oprf::test::test_uniformity;
use concrete_csprng::seeders::Seed;
@@ -214,7 +314,7 @@ pub(crate) mod test {
};
test_uniformity(1 << random_bits_count, &|seed| {
let img = sk.par_generate_oblivious_pseudo_random_unsigned_integer(
let img = sk.par_generate_oblivious_pseudo_random_unsigned_integer_bounded(
Seed(seed as u128),
random_bits_count,
num_blocks as u64,
@@ -223,9 +323,9 @@ pub(crate) mod test {
});
test_uniformity(1 << random_bits_count, &|seed| {
let img = sk.par_generate_oblivious_pseudo_random_signed_integer(
let img = sk.par_generate_oblivious_pseudo_random_signed_integer_bounded(
Seed(seed as u128),
SignedRandomizationSpec::Unsigned { random_bits_count },
random_bits_count,
num_blocks as u64,
);
let result = ck.decrypt_signed::<i64>(&img);
@@ -238,7 +338,6 @@ pub(crate) mod test {
test_uniformity(1 << (2 * num_blocks), &|seed| {
let img = sk.par_generate_oblivious_pseudo_random_signed_integer(
Seed(seed as u128),
SignedRandomizationSpec::FullSigned,
num_blocks as u64,
);