Skip to content

Commit

Permalink
feat(tfhe): add FheUint2048
Browse files Browse the repository at this point in the history
  • Loading branch information
tmontaigu authored and IceTDrinker committed Jun 12, 2024
1 parent 46115eb commit db2389a
Show file tree
Hide file tree
Showing 17 changed files with 301 additions and 61 deletions.
65 changes: 65 additions & 0 deletions tfhe/c_api_tests/test_high_level_2048.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <tfhe.h>

#include <assert.h>
#include <inttypes.h>
#include <stdio.h>

int uint2048_client_key(const ClientKey *client_key) {
int ok;
FheUint2048 *lhs = NULL;
FheUint2048 *rhs = NULL;
FheBool *result = NULL;
FheUint64 *cast_result = NULL;
U2048 lhs_clear = {.words = {0}};
U2048 rhs_clear = {.words = {0}};
bool result_clear = true;

for (size_t i = 0; i < 32; ++i) {
lhs_clear.words[i] = i;
rhs_clear.words[i] = UINT64_MAX - i;
}

ok = fhe_uint2048_try_encrypt_with_client_key_u2048(lhs_clear, client_key, &lhs);
assert(ok == 0);

ok = fhe_uint2048_try_encrypt_with_client_key_u2048(rhs_clear, client_key, &rhs);
assert(ok == 0);

ok = fhe_uint2048_eq(lhs, rhs, &result);
assert(ok == 0);

ok = fhe_bool_decrypt(result, client_key, &result_clear);
assert(ok == 0);

assert(result_clear == false);

fhe_uint2048_destroy(lhs);
fhe_uint2048_destroy(rhs);
fhe_bool_destroy(result);
return ok;
}

int main(void) {
int ok = 0;
ConfigBuilder *builder;
Config *config;

config_builder_default(&builder);
config_builder_build(builder, &config);

ClientKey *client_key = NULL;
ServerKey *server_key = NULL;
PublicKey *public_key = NULL;

generate_keys(config, &client_key, &server_key);
public_key_new(client_key, &public_key);

set_server_key(server_key);

uint2048_client_key(client_key);

client_key_destroy(client_key);
public_key_destroy(public_key);
server_key_destroy(server_key);
return ok;
}
42 changes: 32 additions & 10 deletions tfhe/js_on_wasm_tests/test-hlapi-unsigned.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const {
const {
randomBytes,
} = require('node:crypto');
const {FheUint2048} = require("../pkg");

const U256_MAX = BigInt("115792089237316195423570985008687907853269984665640564039457584007913129639935");
const U128_MAX = BigInt("340282366920938463463374607431768211455");
Expand All @@ -40,8 +41,16 @@ const U32_MAX = 4294967295;
//
// Note that the test hlapi_panic
// purposefully creates a panic, to some panic message
// will be printed and tess will be ok
// will be printed and test will be ok
init_panic_hook();
function generateRandomBigInt(bitLength) {
const bytesNeeded = Math.ceil(bitLength / 8);
const randomBytesBuffer = randomBytes(bytesNeeded);

// Convert random bytes to BigInt
return BigInt(`0x${randomBytesBuffer.toString('hex')}`);
}


// Here integers are not enabled
// but we try to use them, so an error should be returned
Expand Down Expand Up @@ -647,15 +656,6 @@ test('hlapi_compact_public_key_encrypt_decrypt_uint256_big_list_compact', (t) =>
hlapi_compact_public_key_encrypt_decrypt_uint256_list_compact(config);
});

function generateRandomBigInt(bitLength) {
const bytesNeeded = Math.ceil(bitLength / 8);
const randomBytesBuffer = randomBytes(bytesNeeded);

// Convert random bytes to BigInt
const randomBigInt = BigInt(`0x${randomBytesBuffer.toString('hex')}`);

return randomBigInt;
}

test('hlapi_compact_public_key_encrypt_and_prove_compact_uint256', (t) => {
let block_params = new ShortintParameters(ShortintParametersName.PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS_TUNIFORM_2M40);
Expand Down Expand Up @@ -692,3 +692,25 @@ test('hlapi_compact_public_key_encrypt_and_prove_compact_uint256', (t) => {
}
}
});


test('hlapi_encrypt_2048_bits', (t) => {

let config = TfheConfigBuilder.default()
.build();

let clientKey = TfheClientKey.generate(config);

let values = [
(BigInt(1) << BigInt(2048)) - BigInt(1),
generateRandomBigInt(2048),
generateRandomBigInt(2048),
generateRandomBigInt(2048),
];

for (const value of values) {
let encrypted = FheUint2048.encrypt_with_client_key(value, clientKey);
let decrypted = encrypted.decrypt(clientKey);
assert.deepStrictEqual(decrypted, value);
}
});
2 changes: 2 additions & 0 deletions tfhe/src/c_api/high_level_api/integers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::c_api::high_level_api::i128::I128;
use crate::c_api::high_level_api::i256::I256;
use crate::c_api::high_level_api::keys::CompactPublicKey;
use crate::c_api::high_level_api::u128::U128;
use crate::c_api::high_level_api::u2048::U2048;
use crate::c_api::high_level_api::u256::U256;
use crate::c_api::utils::*;
use crate::high_level_api::prelude::*;
Expand Down Expand Up @@ -593,6 +594,7 @@ create_integer_wrapper_type!(name: FheUint64, clear_scalar_type: u64);
create_integer_wrapper_type!(name: FheUint128, clear_scalar_type: U128);
create_integer_wrapper_type!(name: FheUint160, clear_scalar_type: U256);
create_integer_wrapper_type!(name: FheUint256, clear_scalar_type: U256);
create_integer_wrapper_type!(name: FheUint2048, clear_scalar_type: U2048);

// compact list encryption is not part of the crate_integer_wrapper_type
// as for U128 and U256 clear scalar types, the function to use is different
Expand Down
1 change: 1 addition & 0 deletions tfhe/src/c_api/high_level_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod integers;
pub mod keys;
mod threading;
pub mod u128;
pub mod u2048;
pub mod u256;
mod utils;
#[cfg(feature = "zk-pok-experimental")]
Expand Down
88 changes: 88 additions & 0 deletions tfhe/src/c_api/high_level_api/u2048.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::c_api::utils::*;
use std::os::raw::c_int;

#[derive(Copy, Clone)]
#[repr(C)]
pub struct U2048 {
words: [u64; 32],
}

impl From<crate::integer::bigint::U2048> for U2048 {
fn from(value: crate::integer::bigint::U2048) -> Self {
Self { words: value.0 }
}
}

impl From<U2048> for crate::integer::bigint::U2048 {
fn from(value: U2048) -> Self {
Self(value.words)
}
}

/// Creates a U2048 from little endian bytes
///
/// len must be 256
#[no_mangle]
pub unsafe extern "C" fn U2048_from_little_endian_bytes(
input: *const u8,
len: usize,
result: *mut U2048,
) -> c_int {
catch_panic(|| {
let mut inner = crate::integer::bigint::U2048::default();

let input = std::slice::from_raw_parts(input, len);
inner.copy_from_le_byte_slice(input);

*result = U2048::from(inner);
})
}

/// Creates a U2048 from big endian bytes
///
/// len must be 256
#[no_mangle]
pub unsafe extern "C" fn U2048_from_big_endian_bytes(
input: *const u8,
len: usize,
result: *mut U2048,
) -> c_int {
catch_panic(|| {
let mut inner = crate::integer::bigint::U2048::default();

let input = std::slice::from_raw_parts(input, len);
inner.copy_from_be_byte_slice(input);

*result = U2048::from(inner);
})
}

/// len must be 256
#[no_mangle]
pub unsafe extern "C" fn U2048_little_endian_bytes(
input: U2048,
result: *mut u8,
len: usize,
) -> c_int {
catch_panic(|| {
check_ptr_is_non_null_and_aligned(result).unwrap();

let bytes = std::slice::from_raw_parts_mut(result, len);
crate::integer::bigint::U2048::from(input).copy_to_le_byte_slice(bytes);
})
}

/// len must be 256
#[no_mangle]
pub unsafe extern "C" fn U2048_big_endian_bytes(
input: U2048,
result: *mut u8,
len: usize,
) -> c_int {
catch_panic(|| {
check_ptr_is_non_null_and_aligned(result).unwrap();

let bytes = std::slice::from_raw_parts_mut(result, len);
crate::integer::bigint::U2048::from(input).copy_to_be_byte_slice(bytes);
})
}
1 change: 1 addition & 0 deletions tfhe/src/c_api/high_level_api/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl_c_api_integer_type!(crate::c_api::high_level_api::u128::U128 => u128);
impl_c_api_integer_type!(crate::c_api::high_level_api::i128::I128 => i128);
impl_c_api_integer_type!(crate::c_api::high_level_api::u256::U256 => crate::integer::U256);
impl_c_api_integer_type!(crate::c_api::high_level_api::i256::I256 => crate::integer::I256);
impl_c_api_integer_type!(crate::c_api::high_level_api::u2048::U2048 => crate::integer::bigint::U2048);

macro_rules! impl_destroy_on_type {
($wrapper_type:ty) => {
Expand Down
2 changes: 1 addition & 1 deletion tfhe/src/high_level_api/integers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
expand_pub_use_fhe_type!(
pub use unsigned{
FheUint2, FheUint4, FheUint6, FheUint8, FheUint10, FheUint12, FheUint14, FheUint16,
FheUint32, FheUint64, FheUint128, FheUint160, FheUint256
FheUint32, FheUint64, FheUint128, FheUint160, FheUint256, FheUint2048
};
);

Expand Down
2 changes: 1 addition & 1 deletion tfhe/src/high_level_api/integers/unsigned/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub use base::{FheUint, FheUintId};
expand_pub_use_fhe_type!(
pub use static_{
FheUint2, FheUint4, FheUint6, FheUint8, FheUint10, FheUint12, FheUint14, FheUint16,
FheUint32, FheUint64, FheUint128, FheUint160, FheUint256
FheUint32, FheUint64, FheUint128, FheUint160, FheUint256, FheUint2048
};
);

Expand Down
Loading

0 comments on commit db2389a

Please sign in to comment.