mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-09 14:47:56 -05:00
chore(integer): move u256 into its own mod
This commit is contained in:
@@ -69,12 +69,12 @@ where
|
||||
let encrypt_two_values = || {
|
||||
let clearlow = rng.gen::<u128>();
|
||||
let clearhigh = rng.gen::<u128>();
|
||||
let clear_0 = tfhe::integer::client_key::U256::from((clearlow, clearhigh));
|
||||
let clear_0 = tfhe::integer::U256::from((clearlow, clearhigh));
|
||||
let mut ct_0 = cks.encrypt_radix(clear_0, num_block);
|
||||
|
||||
let clearlow = rng.gen::<u128>();
|
||||
let clearhigh = rng.gen::<u128>();
|
||||
let clear_1 = tfhe::integer::client_key::U256::from((clearlow, clearhigh));
|
||||
let clear_1 = tfhe::integer::U256::from((clearlow, clearhigh));
|
||||
let mut ct_1 = cks.encrypt_radix(clear_1, num_block);
|
||||
|
||||
// Raise the degree, so as to ensure worst case path in operations
|
||||
@@ -83,7 +83,7 @@ where
|
||||
// Raise the degree, so as to ensure worst case path in operations
|
||||
let clearlow = rng.gen::<u128>();
|
||||
let clearhigh = rng.gen::<u128>();
|
||||
let clear_2 = tfhe::integer::client_key::U256::from((clearlow, clearhigh));
|
||||
let clear_2 = tfhe::integer::U256::from((clearlow, clearhigh));
|
||||
let ct_2 = cks.encrypt_radix(clear_2, num_block);
|
||||
sks.unchecked_add_assign(&mut ct_0, &ct_2);
|
||||
sks.unchecked_add_assign(&mut ct_1, &ct_2);
|
||||
@@ -127,7 +127,7 @@ where
|
||||
let clearlow = rng.gen::<u128>();
|
||||
let clearhigh = rng.gen::<u128>();
|
||||
|
||||
let clear_0 = tfhe::integer::client_key::U256::from((clearlow, clearhigh));
|
||||
let clear_0 = tfhe::integer::U256::from((clearlow, clearhigh));
|
||||
|
||||
let mut ct_0 = cks.encrypt_radix(clear_0, num_block);
|
||||
|
||||
@@ -137,7 +137,7 @@ where
|
||||
// Raise the degree, so as to ensure worst case path in operations
|
||||
let clearlow = rng.gen::<u128>();
|
||||
let clearhigh = rng.gen::<u128>();
|
||||
let clear_2 = tfhe::integer::client_key::U256::from((clearlow, clearhigh));
|
||||
let clear_2 = tfhe::integer::U256::from((clearlow, clearhigh));
|
||||
let ct_2 = cks.encrypt_radix(clear_2, num_block);
|
||||
sks.unchecked_add_assign(&mut ct_0, &ct_2);
|
||||
|
||||
@@ -178,7 +178,7 @@ where
|
||||
let clearlow = rng.gen::<u128>();
|
||||
let clearhigh = rng.gen::<u128>();
|
||||
|
||||
let clear_0 = tfhe::integer::client_key::U256::from((clearlow, clearhigh));
|
||||
let clear_0 = tfhe::integer::U256::from((clearlow, clearhigh));
|
||||
let ct_0 = cks.encrypt_radix(clear_0, num_block);
|
||||
|
||||
let clear_1 = rng.gen::<u64>();
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::shortint::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use utils::radix_decomposition;
|
||||
|
||||
use crate::integer::U256;
|
||||
pub use crt::CrtClientKey;
|
||||
pub use radix::RadixClientKey;
|
||||
|
||||
@@ -79,30 +80,6 @@ impl ClearText for u128 {
|
||||
unsafe { std::slice::from_raw_parts_mut(u128_slc.as_mut_ptr() as *mut u64, 2) }
|
||||
}
|
||||
}
|
||||
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct U256([u128; 2]);
|
||||
|
||||
impl U256 {
|
||||
#[inline]
|
||||
pub fn low(&self) -> u128 {
|
||||
self.0[0]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn high(&self) -> u128 {
|
||||
self.0[1]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn low_mut(&mut self) -> &mut u128 {
|
||||
&mut self.0[0]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn high_mut(&mut self) -> &mut u128 {
|
||||
&mut self.0[1]
|
||||
}
|
||||
}
|
||||
|
||||
impl ClearText for U256 {
|
||||
fn as_words(&self) -> &[u64] {
|
||||
@@ -116,66 +93,6 @@ impl ClearText for U256 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl rand::distributions::Distribution<U256> for rand::distributions::Standard {
|
||||
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> U256 {
|
||||
let low = rng.gen::<u128>();
|
||||
let high = rng.gen::<u128>();
|
||||
U256::from((low, high))
|
||||
}
|
||||
}
|
||||
|
||||
// Since we store as [low, high], deriving ord
|
||||
// would produces bad ordering
|
||||
impl std::cmp::Ord for U256 {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
let high_bits_ord = self.high().cmp(&other.high());
|
||||
if let std::cmp::Ordering::Equal = high_bits_ord {
|
||||
self.low().cmp(&other.low())
|
||||
} else {
|
||||
high_bits_ord
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add<Self> for U256 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
let (new_low, has_overflowed) = self.low().overflowing_add(rhs.low());
|
||||
let new_high = self
|
||||
.high()
|
||||
.wrapping_add(rhs.high())
|
||||
.wrapping_add(u128::from(has_overflowed));
|
||||
|
||||
Self::from((new_low, new_high))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign<Self> for U256 {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd for U256 {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(u128, u128)> for U256 {
|
||||
fn from(v: (u128, u128)) -> Self {
|
||||
Self([v.0, v.1])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for U256 {
|
||||
fn from(value: u128) -> Self {
|
||||
Self::from((value, 0))
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientKey {
|
||||
/// Creates a Client Key.
|
||||
///
|
||||
|
||||
@@ -57,11 +57,13 @@ pub mod client_key;
|
||||
pub mod keycache;
|
||||
pub mod parameters;
|
||||
pub mod server_key;
|
||||
pub mod u256;
|
||||
pub mod wopbs;
|
||||
|
||||
pub use ciphertext::{CrtCiphertext, IntegerCiphertext, RadixCiphertext};
|
||||
pub use client_key::{ClientKey, CrtClientKey, RadixClientKey};
|
||||
pub use server_key::{CheckError, ServerKey};
|
||||
pub use u256::U256;
|
||||
|
||||
/// Generate a couple of client and server keys with given parameters
|
||||
///
|
||||
|
||||
@@ -861,8 +861,7 @@ impl<'a> Comparator<'a> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Comparator;
|
||||
use crate::integer::client_key::U256;
|
||||
use crate::integer::{gen_keys, RadixCiphertext};
|
||||
use crate::integer::{gen_keys, RadixCiphertext, U256};
|
||||
use crate::shortint::Parameters;
|
||||
use rand;
|
||||
use rand::prelude::*;
|
||||
|
||||
@@ -152,10 +152,10 @@ fn integer_encrypt_decrypt_256_bits_specific_values(param: Parameters) {
|
||||
{
|
||||
let a = (u64::MAX as u128) << 64;
|
||||
let b = 0;
|
||||
let clear = crate::integer::client_key::U256::from((a, b));
|
||||
let clear = crate::integer::U256::from((a, b));
|
||||
let ct = cks.encrypt_radix(clear, num_block);
|
||||
|
||||
let mut dec = crate::integer::client_key::U256::from((0, 0));
|
||||
let mut dec = crate::integer::U256::from((0, 0));
|
||||
cks.decrypt_radix_into(&ct, &mut dec);
|
||||
|
||||
assert_eq!(clear, dec);
|
||||
@@ -163,10 +163,10 @@ fn integer_encrypt_decrypt_256_bits_specific_values(param: Parameters) {
|
||||
{
|
||||
let a = 0;
|
||||
let b = u128::MAX;
|
||||
let clear = crate::integer::client_key::U256::from((a, b));
|
||||
let clear = crate::integer::U256::from((a, b));
|
||||
let ct = cks.encrypt_radix(clear, num_block);
|
||||
|
||||
let mut dec = crate::integer::client_key::U256::from((0, 0));
|
||||
let mut dec = crate::integer::U256::from((0, 0));
|
||||
cks.decrypt_radix_into(&ct, &mut dec);
|
||||
|
||||
assert_eq!(clear, dec);
|
||||
@@ -184,13 +184,13 @@ fn integer_encrypt_decrypt_256_bits(param: Parameters) {
|
||||
let clear0 = rng.gen::<u128>();
|
||||
let clear1 = rng.gen::<u128>();
|
||||
|
||||
let clear = crate::integer::client_key::U256::from((clear0, clear1));
|
||||
let clear = crate::integer::U256::from((clear0, clear1));
|
||||
|
||||
//encryption
|
||||
let ct = cks.encrypt_radix(clear, num_block);
|
||||
|
||||
// decryption
|
||||
let mut dec = crate::integer::client_key::U256::from((0, 0));
|
||||
let mut dec = crate::integer::U256::default();
|
||||
cks.decrypt_radix_into(&ct, &mut dec);
|
||||
|
||||
// assert
|
||||
|
||||
84
tfhe/src/integer/u256.rs
Normal file
84
tfhe/src/integer/u256.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct U256(pub(crate) [u128; 2]);
|
||||
|
||||
impl U256 {
|
||||
#[inline]
|
||||
pub fn low(&self) -> u128 {
|
||||
self.0[0]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn high(&self) -> u128 {
|
||||
self.0[1]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn low_mut(&mut self) -> &mut u128 {
|
||||
&mut self.0[0]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn high_mut(&mut self) -> &mut u128 {
|
||||
&mut self.0[1]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl rand::distributions::Distribution<U256> for rand::distributions::Standard {
|
||||
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> U256 {
|
||||
let low = rng.gen::<u128>();
|
||||
let high = rng.gen::<u128>();
|
||||
U256::from((low, high))
|
||||
}
|
||||
}
|
||||
|
||||
// Since we store as [low, high], deriving ord
|
||||
// would produces bad ordering
|
||||
impl std::cmp::Ord for U256 {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
let high_bits_ord = self.high().cmp(&other.high());
|
||||
if let std::cmp::Ordering::Equal = high_bits_ord {
|
||||
self.low().cmp(&other.low())
|
||||
} else {
|
||||
high_bits_ord
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add<Self> for U256 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
let (new_low, has_overflowed) = self.low().overflowing_add(rhs.low());
|
||||
let new_high = self
|
||||
.high()
|
||||
.wrapping_add(rhs.high())
|
||||
.wrapping_add(u128::from(has_overflowed));
|
||||
|
||||
Self::from((new_low, new_high))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign<Self> for U256 {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::cmp::PartialOrd for U256 {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(u128, u128)> for U256 {
|
||||
fn from(v: (u128, u128)) -> Self {
|
||||
Self([v.0, v.1])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for U256 {
|
||||
fn from(value: u128) -> Self {
|
||||
Self::from((value, 0))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user