Skip to content

Commit 396f30f

Browse files
committed
feat(c_api): add new integer types
1 parent 10b8214 commit 396f30f

File tree

9 files changed

+465
-4
lines changed

9 files changed

+465
-4
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ clippy_rustdoc_gpu: install_rs_check_toolchain
385385
.PHONY: clippy_c_api # Run clippy lints enabling the boolean, shortint and the C API
386386
clippy_c_api: install_rs_check_toolchain
387387
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy \
388-
--features=boolean-c-api,shortint-c-api,high-level-c-api \
388+
--features=boolean-c-api,shortint-c-api,high-level-c-api,extended-types \
389389
-p $(TFHE_SPEC) -- --no-deps -D warnings
390390

391391
.PHONY: clippy_js_wasm_api # Run clippy lints enabling the boolean, shortint, integer and the js wasm API
@@ -512,13 +512,13 @@ build_tfhe_coverage: install_rs_build_toolchain
512512
.PHONY: build_c_api # Build the C API for boolean, shortint and integer
513513
build_c_api: install_rs_check_toolchain
514514
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
515-
--features=boolean-c-api,shortint-c-api,high-level-c-api,zk-pok \
515+
--features=boolean-c-api,shortint-c-api,high-level-c-api,zk-pok,extended-types \
516516
-p $(TFHE_SPEC)
517517

518518
.PHONY: build_c_api_gpu # Build the C API for boolean, shortint and integer
519519
build_c_api_gpu: install_rs_check_toolchain
520520
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) build --profile $(CARGO_PROFILE) \
521-
--features=boolean-c-api,shortint-c-api,high-level-c-api,zk-pok,gpu \
521+
--features=boolean-c-api,shortint-c-api,high-level-c-api,zk-pok,extended-types,gpu \
522522
-p $(TFHE_SPEC)
523523

524524
.PHONY: build_c_api_experimental_deterministic_fft # Build the C API for boolean, shortint and integer with experimental deterministic FFT
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use crate::c_api::utils::*;
2+
use std::os::raw::c_int;
3+
4+
#[derive(Copy, Clone)]
5+
#[repr(C)]
6+
pub struct I1024 {
7+
words: [u64; 16],
8+
}
9+
10+
impl From<crate::integer::bigint::I1024> for I1024 {
11+
fn from(value: crate::integer::bigint::I1024) -> Self {
12+
Self { words: value.0 }
13+
}
14+
}
15+
16+
impl From<I1024> for crate::integer::bigint::I1024 {
17+
fn from(value: I1024) -> Self {
18+
Self(value.words)
19+
}
20+
}
21+
22+
/// Creates a I1024 from little endian bytes
23+
///
24+
/// len must be 128
25+
#[no_mangle]
26+
pub unsafe extern "C" fn I1024_from_little_endian_bytes(
27+
input: *const u8,
28+
len: usize,
29+
result: *mut I1024,
30+
) -> c_int {
31+
catch_panic(|| {
32+
let mut inner = crate::integer::bigint::I1024::default();
33+
34+
let input = std::slice::from_raw_parts(input, len);
35+
inner.copy_from_le_byte_slice(input);
36+
37+
*result = I1024::from(inner);
38+
})
39+
}
40+
41+
/// Creates a I1024 from big endian bytes
42+
///
43+
/// len must be 128
44+
#[no_mangle]
45+
pub unsafe extern "C" fn I1024_from_big_endian_bytes(
46+
input: *const u8,
47+
len: usize,
48+
result: *mut I1024,
49+
) -> c_int {
50+
catch_panic(|| {
51+
let mut inner = crate::integer::bigint::I1024::default();
52+
53+
let input = std::slice::from_raw_parts(input, len);
54+
inner.copy_from_be_byte_slice(input);
55+
56+
*result = I1024::from(inner);
57+
})
58+
}
59+
60+
/// len must be 128
61+
#[no_mangle]
62+
pub unsafe extern "C" fn I1024_little_endian_bytes(
63+
input: I1024,
64+
result: *mut u8,
65+
len: usize,
66+
) -> c_int {
67+
catch_panic(|| {
68+
check_ptr_is_non_null_and_aligned(result).unwrap();
69+
70+
let bytes = std::slice::from_raw_parts_mut(result, len);
71+
crate::integer::bigint::I1024::from(input).copy_to_le_byte_slice(bytes);
72+
})
73+
}
74+
75+
/// len must be 128
76+
#[no_mangle]
77+
pub unsafe extern "C" fn I1024_big_endian_bytes(
78+
input: I1024,
79+
result: *mut u8,
80+
len: usize,
81+
) -> c_int {
82+
catch_panic(|| {
83+
check_ptr_is_non_null_and_aligned(result).unwrap();
84+
85+
let bytes = std::slice::from_raw_parts_mut(result, len);
86+
crate::integer::bigint::I1024::from(input).copy_to_be_byte_slice(bytes);
87+
})
88+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use crate::c_api::utils::*;
2+
use std::os::raw::c_int;
3+
4+
#[derive(Copy, Clone)]
5+
#[repr(C)]
6+
pub struct I2048 {
7+
words: [u64; 32],
8+
}
9+
10+
impl From<crate::integer::bigint::I2048> for I2048 {
11+
fn from(value: crate::integer::bigint::I2048) -> Self {
12+
Self { words: value.0 }
13+
}
14+
}
15+
16+
impl From<I2048> for crate::integer::bigint::I2048 {
17+
fn from(value: I2048) -> Self {
18+
Self(value.words)
19+
}
20+
}
21+
22+
/// Creates a I2048 from little endian bytes
23+
///
24+
/// len must be 256
25+
#[no_mangle]
26+
pub unsafe extern "C" fn I2048_from_little_endian_bytes(
27+
input: *const u8,
28+
len: usize,
29+
result: *mut I2048,
30+
) -> c_int {
31+
catch_panic(|| {
32+
let mut inner = crate::integer::bigint::I2048::default();
33+
34+
let input = std::slice::from_raw_parts(input, len);
35+
inner.copy_from_le_byte_slice(input);
36+
37+
*result = I2048::from(inner);
38+
})
39+
}
40+
41+
/// Creates a I2048 from big endian bytes
42+
///
43+
/// len must be 256
44+
#[no_mangle]
45+
pub unsafe extern "C" fn I2048_from_big_endian_bytes(
46+
input: *const u8,
47+
len: usize,
48+
result: *mut I2048,
49+
) -> c_int {
50+
catch_panic(|| {
51+
let mut inner = crate::integer::bigint::I2048::default();
52+
53+
let input = std::slice::from_raw_parts(input, len);
54+
inner.copy_from_be_byte_slice(input);
55+
56+
*result = I2048::from(inner);
57+
})
58+
}
59+
60+
/// len must be 256
61+
#[no_mangle]
62+
pub unsafe extern "C" fn I2048_little_endian_bytes(
63+
input: I2048,
64+
result: *mut u8,
65+
len: usize,
66+
) -> c_int {
67+
catch_panic(|| {
68+
check_ptr_is_non_null_and_aligned(result).unwrap();
69+
70+
let bytes = std::slice::from_raw_parts_mut(result, len);
71+
crate::integer::bigint::I2048::from(input).copy_to_le_byte_slice(bytes);
72+
})
73+
}
74+
75+
/// len must be 256
76+
#[no_mangle]
77+
pub unsafe extern "C" fn I2048_big_endian_bytes(
78+
input: I2048,
79+
result: *mut u8,
80+
len: usize,
81+
) -> c_int {
82+
catch_panic(|| {
83+
check_ptr_is_non_null_and_aligned(result).unwrap();
84+
85+
let bytes = std::slice::from_raw_parts_mut(result, len);
86+
crate::integer::bigint::I2048::from(input).copy_to_be_byte_slice(bytes);
87+
})
88+
}

tfhe/src/c_api/high_level_api/i256.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use crate::c_api::utils::*;
2+
use std::os::raw::c_int;
3+
14
/// w0, w1, w2, w3 are words in little endian order
25
/// using two's complement representation
36
#[repr(C)]
@@ -25,3 +28,67 @@ impl From<I256> for crate::integer::I256 {
2528
Self([value.w0, value.w1, value.w2, value.w3])
2629
}
2730
}
31+
32+
/// Creates a I256 from little endian bytes
33+
///
34+
/// len must be 32
35+
#[no_mangle]
36+
pub unsafe extern "C" fn i256_from_little_endian_bytes(
37+
input: *const u8,
38+
len: usize,
39+
result: *mut I256,
40+
) -> c_int {
41+
catch_panic(|| {
42+
let mut inner = crate::integer::I256::default();
43+
44+
let input = std::slice::from_raw_parts(input, len);
45+
inner.copy_from_le_byte_slice(input);
46+
47+
*result = I256::from(inner);
48+
})
49+
}
50+
51+
/// Creates a I256 from big endian bytes
52+
///
53+
/// len must be 32
54+
#[no_mangle]
55+
pub unsafe extern "C" fn i256_from_big_endian_bytes(
56+
input: *const u8,
57+
len: usize,
58+
result: *mut I256,
59+
) -> c_int {
60+
catch_panic(|| {
61+
let mut inner = crate::integer::I256::default();
62+
63+
let input = std::slice::from_raw_parts(input, len);
64+
inner.copy_from_be_byte_slice(input);
65+
66+
*result = I256::from(inner);
67+
})
68+
}
69+
70+
/// len must be 32
71+
#[no_mangle]
72+
pub unsafe extern "C" fn i256_little_endian_bytes(
73+
input: I256,
74+
result: *mut u8,
75+
len: usize,
76+
) -> c_int {
77+
catch_panic(|| {
78+
check_ptr_is_non_null_and_aligned(result).unwrap();
79+
80+
let bytes = std::slice::from_raw_parts_mut(result, len);
81+
crate::integer::I256::from(input).copy_to_le_byte_slice(bytes);
82+
})
83+
}
84+
85+
/// len must be 32
86+
#[no_mangle]
87+
pub unsafe extern "C" fn i256_big_endian_bytes(input: I256, result: *mut u8, len: usize) -> c_int {
88+
catch_panic(|| {
89+
check_ptr_is_non_null_and_aligned(result).unwrap();
90+
91+
let bytes = std::slice::from_raw_parts_mut(result, len);
92+
crate::integer::I256::from(input).copy_to_be_byte_slice(bytes);
93+
})
94+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use crate::c_api::utils::*;
2+
use std::os::raw::c_int;
3+
4+
#[derive(Copy, Clone)]
5+
#[repr(C)]
6+
pub struct I512 {
7+
words: [u64; 8],
8+
}
9+
10+
impl From<crate::integer::bigint::I512> for I512 {
11+
fn from(value: crate::integer::bigint::I512) -> Self {
12+
Self { words: value.0 }
13+
}
14+
}
15+
16+
impl From<I512> for crate::integer::bigint::I512 {
17+
fn from(value: I512) -> Self {
18+
Self(value.words)
19+
}
20+
}
21+
22+
/// Creates a I512 from little endian bytes
23+
///
24+
/// len must be 64
25+
#[no_mangle]
26+
pub unsafe extern "C" fn I512_from_little_endian_bytes(
27+
input: *const u8,
28+
len: usize,
29+
result: *mut I512,
30+
) -> c_int {
31+
catch_panic(|| {
32+
let mut inner = crate::integer::bigint::I512::default();
33+
34+
let input = std::slice::from_raw_parts(input, len);
35+
inner.copy_from_le_byte_slice(input);
36+
37+
*result = I512::from(inner);
38+
})
39+
}
40+
41+
/// Creates a I512 from big endian bytes
42+
///
43+
/// len must be 64
44+
#[no_mangle]
45+
pub unsafe extern "C" fn I512_from_big_endian_bytes(
46+
input: *const u8,
47+
len: usize,
48+
result: *mut I512,
49+
) -> c_int {
50+
catch_panic(|| {
51+
let mut inner = crate::integer::bigint::I512::default();
52+
53+
let input = std::slice::from_raw_parts(input, len);
54+
inner.copy_from_be_byte_slice(input);
55+
56+
*result = I512::from(inner);
57+
})
58+
}
59+
60+
/// len must be 64
61+
#[no_mangle]
62+
pub unsafe extern "C" fn I512_little_endian_bytes(
63+
input: I512,
64+
result: *mut u8,
65+
len: usize,
66+
) -> c_int {
67+
catch_panic(|| {
68+
check_ptr_is_non_null_and_aligned(result).unwrap();
69+
70+
let bytes = std::slice::from_raw_parts_mut(result, len);
71+
crate::integer::bigint::I512::from(input).copy_to_le_byte_slice(bytes);
72+
})
73+
}
74+
75+
/// len must be 64
76+
#[no_mangle]
77+
pub unsafe extern "C" fn I512_big_endian_bytes(input: I512, result: *mut u8, len: usize) -> c_int {
78+
catch_panic(|| {
79+
check_ptr_is_non_null_and_aligned(result).unwrap();
80+
81+
let bytes = std::slice::from_raw_parts_mut(result, len);
82+
crate::integer::bigint::I512::from(input).copy_to_be_byte_slice(bytes);
83+
})
84+
}

0 commit comments

Comments
 (0)