Compare commits

...

11 Commits

Author SHA1 Message Date
Arthur Meyre
75d7865b77 chore(tfhe): bump version to 0.1.12 2023-03-20 11:18:04 +01:00
sarah el kazdadi
343e0f1613 fix(tfhe): fix faulty comparison in avx512 code 2023-03-20 11:18:04 +01:00
Arthur Meyre
7be5aedc07 chore(ci): change ubuntu mirror urls as the original ones are too slow 2023-03-20 11:18:04 +01:00
Arthur Meyre
155ab13295 chore(ci): silence skipped M1 tests due to cla-bot label 2023-03-20 11:18:04 +01:00
Rui LOPES
049e3518a7 fix(build): remove -- flag from make targets that do not use wasm-pack 2023-03-20 11:18:04 +01:00
Rui LOPES
9fff450f47 fix(build): pass the --features arguments to the wasm-pack command in Makefile js targets 2023-03-20 11:18:04 +01:00
tmontaigu
f1ebadf73d chore(tfhe): bump version to 0.1.11 2023-03-13 17:03:41 +01:00
tmontaigu
61b6db394e fix(shortint): remove wrong large_mod in cmp operations 2023-03-13 16:56:35 +01:00
Arthur Meyre
e4e9cc8489 chore(tfhe): fix typos 2023-03-13 13:39:18 +01:00
aquint-zama
7e6facc08c chore(docs): minor fixes 2023-03-07 17:30:23 +01:00
Arthur Meyre
0bb12ab9ea chore(tfhe): update copyright year 2023-03-07 09:00:04 +01:00
19 changed files with 139 additions and 114 deletions

View File

@@ -88,7 +88,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Slack Notification
if: ${{ always() }}
if: ${{ needs.cargo-builds.result != 'skipped' }}
continue-on-error: true
uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7
env:

56
LICENSE
View File

@@ -1,28 +1,28 @@
BSD 3-Clause Clear License
Copyright © 2022 ZAMA.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of ZAMA nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
THIS SOFTWARE IS PROVIDED BY THE ZAMA AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
ZAMA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
BSD 3-Clause Clear License
Copyright © 2023 ZAMA.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of ZAMA nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
THIS SOFTWARE IS PROVIDED BY THE ZAMA AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
ZAMA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -133,14 +133,14 @@ build_web_js_api: install_rs_build_toolchain
cd tfhe && \
RUSTFLAGS="$(WASM_RUSTFLAGS)" rustup run "$(RS_BUILD_TOOLCHAIN)" \
wasm-pack build --release --target=web \
--features=boolean-client-js-wasm-api,shortint-client-js-wasm-api
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api
.PHONY: build_node_js_api # Build the js API targeting nodejs
build_node_js_api: install_rs_build_toolchain
cd tfhe && \
RUSTFLAGS="$(WASM_RUSTFLAGS)" rustup run "$(RS_BUILD_TOOLCHAIN)" \
wasm-pack build --release --target=nodejs \
--features=boolean-client-js-wasm-api,shortint-client-js-wasm-api
-- --features=boolean-client-js-wasm-api,shortint-client-js-wasm-api
.PHONY: test_core_crypto # Run the tests of the core_crypto module
test_core_crypto: install_rs_build_toolchain

View File

@@ -5,8 +5,8 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# Replace default archive.ubuntu.com with fr mirror
# original archive showed performance issues and is farther away
RUN sed -i 's|^deb http://archive|deb http://fr.archive|g' /etc/apt/sources.list && \
sed -i 's|^deb http://security|deb http://fr.archive|g' /etc/apt/sources.list
RUN sed -i 's|^deb http://archive.ubuntu.com/ubuntu/|deb http://mirror.ubuntu.ikoula.com/|g' /etc/apt/sources.list && \
sed -i 's|^deb http://security.ubuntu.com/ubuntu/|deb http://mirror.ubuntu.ikoula.com/|g' /etc/apt/sources.list
ENV CARGO_TARGET_DIR=/root/tfhe-rs-target

View File

@@ -1,6 +1,6 @@
[package]
name = "tfhe"
version = "0.1.10"
version = "0.1.12"
edition = "2021"
readme = "../README.md"
keywords = ["fully", "homomorphic", "encryption", "fhe", "cryptography"]

View File

@@ -1,28 +1,28 @@
BSD 3-Clause Clear License
Copyright © 2022 ZAMA.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of ZAMA nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
THIS SOFTWARE IS PROVIDED BY THE ZAMA AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
ZAMA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
BSD 3-Clause Clear License
Copyright © 2023 ZAMA.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
3. Neither the name of ZAMA nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
THIS SOFTWARE IS PROVIDED BY THE ZAMA AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
ZAMA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -10,7 +10,7 @@ language = "C"
############## Options for Wrapping the Contents of the Header #################
header = "// Copyright © 2022 ZAMA.\n// All rights reserved."
header = "// Copyright © 2023 ZAMA.\n// All rights reserved."
# trailer = "/* Text to put at the end of the generated file */"
include_guard = "TFHE_RS_C_API_H"
# pragma_once = true

View File

@@ -13,7 +13,7 @@ fn main() {
// We use the client secret key to encrypt a message:
let ct_1 = client_key.encrypt(true);
// We use the server public key to execute the NOT gate:
let ct_not = server_key.not(&ct_1);
@@ -30,12 +30,12 @@ use tfhe::boolean::prelude::*;
fn main() {
// We generate a set of client/server keys, using the default parameters:
let (mut client_key, mut server_key) = gen_keys();
let (client_key, server_key) = gen_keys();
// We use the client secret key to encrypt a message:
let ct_1 = client_key.encrypt(true);
let ct_2 = client_key.encrypt(false);
// We use the server public key to execute the XOR gate:
let ct_xor = server_key.xor(&ct_1, &ct_2);
@@ -47,10 +47,10 @@ fn main() {
## The MUX ternary gate
Let `ct_1, ct_2, ct_3` be three Boolean ciphertexts. Then, the MUX gate (abbreviation of MUtipleXer) is equivalent to the operation:
Let `ct_1, ct_2, ct_3` be three Boolean ciphertexts. Then, the MUX gate (abbreviation of MUltipleXer) is equivalent to the operation:
```r
if ct_1 {
if ct_1 {
return ct_2
} else {
return ct_3
@@ -64,12 +64,12 @@ use tfhe::boolean::prelude::*;
fn main() {
// We generate a set of client/server keys, using the default parameters:
let (mut client_key, mut server_key) = gen_keys();
let (client_key, server_key) = gen_keys();
let bool1 = true;
let bool2 = false;
let bool3 = true;
// We use the client secret key to encrypt a message:
let ct_1 = client_key.encrypt(true);
let ct_2 = client_key.encrypt(false);

View File

@@ -1,7 +1,7 @@
# Save and Load Keys From Files
Since the `ServerKey` and `ClientKey` types both implement the `Serialize` and
`Deserialize` traits, you are free to use any serializer that suits you to save and load the
`Deserialize` traits, you are free to use any serializer that suits you to save and load the
keys to disk.
Here is an example using the `bincode` serialization library, which serializes to a
@@ -48,9 +48,9 @@ fn main() {
let loaded_client_key: ClientKey = bincode::deserialize(&encoded_client_key[..])
.expect("failed to deserialize");
let ct_1 = client_key.encrypt(false);
// We check for equality:
assert_eq!(false, loaded_client_key.decrypt(&ct_1));
}

View File

@@ -81,7 +81,7 @@ use tfhe::boolean::prelude::*;
fn main() {
// Don't consider the following line; you should follow the procedure above.
let (mut client_key, _) = gen_keys();
let (client_key, _) = gen_keys();
//---------------------------- SERVER SIDE
@@ -138,7 +138,7 @@ use tfhe::boolean::prelude::*;
fn main() {
// Don't consider the following lines; you should follow the procedure above.
let (mut client_key, mut server_key) = gen_keys();
let (client_key, server_key) = gen_keys();
let ct_1 = client_key.encrypt(true);
let ct_2 = client_key.encrypt(false);
let encoded_1: Vec<u8> = bincode::serialize(&ct_1).unwrap();
@@ -180,7 +180,7 @@ use tfhe::boolean::prelude::*;
fn main() {
// Don't consider the following lines; you should follow the procedure above.
let (mut client_key, mut server_key) = gen_keys();
let (client_key, server_key) = gen_keys();
let ct_6 = client_key.encrypt(true);
let encoded_output: Vec<u8> = bincode::serialize(&ct_6).unwrap();

View File

@@ -60,7 +60,7 @@ target_compile_options(${EXECUTABLE_NAME} PRIVATE -Werror)
### Commented code of a PBS doubling a 2 bits encrypted message using `TFHE-rs C API`.
The steps required to perform the mutiplication by 2 of a 2 bits ciphertext using a PBS are detailed. This is NOT the most efficient way of doing this operation, but it can help to show the management required to run a PBS manually using the C API.
The steps required to perform the multiplication by 2 of a 2 bits ciphertext using a PBS are detailed. This is NOT the most efficient way of doing this operation, but it can help to show the management required to run a PBS manually using the C API.
WARNING: The following example does not have proper memory management in the error case to make it easier to fit the code on this page.

View File

@@ -9,7 +9,7 @@ Welcome to this tutorial about TFHE-rs `core_crypto` module!
To use `TFHE-rs`, first it has to be added as a dependency in the `Cargo.toml`:
```toml
tfhe = { version = "0.1.10", features = [ "x86_64-unix" ] }
tfhe = { version = "0.1.12", features = [ "x86_64-unix" ] }
```
Here, this enables the `x86_64-unix` feature to have efficient implementations of various algorithms for `x86_64` CPUs on a Unix-like system. The 'unix' suffix indicates that the `UnixSeeder`, which uses `/dev/random` to generate random numbers, is actived as a fallback if no hardware number generator is available, like `rdseed` on `x86_64` or if the [`Randomization Services`](https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc) on Apple platforms are not available. To avoid having the `UnixSeeder` as a potential fallback or to run on non-Unix systems (e.g., Windows), the `x86_64` feature is sufficient.
@@ -20,19 +20,19 @@ In short:
For x86_64-based machines running Unix-like OSes:
```toml
tfhe = { version = "0.1.10", features = ["x86_64-unix"] }
tfhe = { version = "0.1.12", features = ["x86_64-unix"] }
```
For Apple Silicon or aarch64-based machines running Unix-like OSes:
```toml
tfhe = { version = "0.1.10", features = ["aarch64-unix"] }
tfhe = { version = "0.1.12", features = ["aarch64-unix"] }
```
For x86_64-based machines with the [`rdseed instruction`](https://en.wikipedia.org/wiki/RDRAND) running Windows:
```toml
tfhe = { version = "0.1.10", features = ["x86_64"] }
tfhe = { version = "0.1.12", features = ["x86_64"] }
```
### Commented code to double a 2 bits message in a leveled fashion and using a PBS with the `core_crypto` module.
@@ -137,7 +137,7 @@ pub fn main() {
);
// Decrypt the cleartext multiplication result
let cleartext_multipliation_plaintext: Plaintext<u64> =
let cleartext_multiplication_plaintext: Plaintext<u64> =
decrypt_lwe_ciphertext(&small_lwe_sk, &cleartext_multiplication_ct);
// Create a SignedDecomposer to perform the rounding of the decrypted plaintext
@@ -148,7 +148,7 @@ pub fn main() {
// Round and remove our encoding
let cleartext_multiplication_result: u64 =
signed_decomposer.closest_representable(cleartext_multipliation_plaintext.0) / delta;
signed_decomposer.closest_representable(cleartext_multiplication_plaintext.0) / delta;
println!("Checking result...");
assert_eq!(6, cleartext_multiplication_result);

View File

@@ -5,7 +5,7 @@
To use `TFHE-rs` in your project, you first need to add it as a dependency in your `Cargo.toml`:
```toml
tfhe = { version = "0.1.10", features = [ "boolean", "shortint", "x86_64-unix" ] }
tfhe = { version = "0.1.12", features = [ "boolean", "shortint", "x86_64-unix" ] }
```
## Choosing your features

View File

@@ -24,7 +24,7 @@ use tfhe::boolean::prelude::*;
fn main() {
// We generate a set of client/server keys, using the default parameters:
let (mut client_key, mut server_key) = gen_keys();
let (client_key, server_key) = gen_keys();
// We use the client secret key to encrypt two messages:
let ct_1 = client_key.encrypt(true);

View File

@@ -65,7 +65,7 @@ where
);
assert!(
output.len() == lhs.len(),
"output (len: {}) and rhs (lhs: {}) must have the same length",
"output (len: {}) and rhs (len: {}) must have the same length",
output.len(),
lhs.len()
);
@@ -174,7 +174,7 @@ where
);
assert!(
output.len() == lhs.len(),
"output (len: {}) and rhs (lhs: {}) must have the same length",
"output (len: {}) and rhs (len: {}) must have the same length",
output.len(),
lhs.len()
);

View File

@@ -105,7 +105,7 @@ pub unsafe fn mm512_cvtpd_epi64(x: __m512d) -> __m512i {
// extract the 63rd sign bit
let sign_is_negative_mask =
_mm512_cmpneq_epi64_mask(_mm512_srli_epi64::<63>(bits), _mm512_set1_epi64(1));
_mm512_cmpeq_epi64_mask(_mm512_srli_epi64::<63>(bits), _mm512_set1_epi64(1));
// we need to shift the mantissa by some value that may be negative, so we first shift it to
// the left by the maximum amount, then shift it to the right by our value plus the offset we

View File

@@ -19,11 +19,10 @@ impl ShortintEngine {
ct_left: &mut Ciphertext,
ct_right: &Ciphertext,
) -> EngineResult<()> {
let modulus = (ct_right.degree.0 + 1) as u64;
let modulus_msg = ct_left.message_modulus.0 as u64;
let large_mod = modulus * modulus_msg;
let modulus_right = (ct_right.degree.0 + 1) as u64;
let modulus_left = ct_left.message_modulus.0 as u64;
self.unchecked_functional_bivariate_pbs_assign(server_key, ct_left, ct_right, |x| {
(((x % large_mod / modulus) % modulus_msg) > (x % modulus_msg)) as u64
(((x / modulus_right) % modulus_left) > (x % modulus_left)) as u64
})?;
ct_left.degree.0 = 1;
@@ -73,11 +72,10 @@ impl ShortintEngine {
ct_left: &mut Ciphertext,
ct_right: &Ciphertext,
) -> EngineResult<()> {
let modulus = (ct_right.degree.0 + 1) as u64;
let modulus_msg = ct_left.message_modulus.0 as u64;
let large_mod = modulus * modulus_msg;
let modulus_right = (ct_right.degree.0 + 1) as u64;
let modulus_left = ct_left.message_modulus.0 as u64;
self.unchecked_functional_bivariate_pbs_assign(server_key, ct_left, ct_right, |x| {
(((x % large_mod / modulus) % modulus_msg) >= (x % modulus_msg)) as u64
(((x / modulus_right) % modulus_left) >= (x % modulus_left)) as u64
})?;
ct_left.degree.0 = 1;
@@ -126,11 +124,10 @@ impl ShortintEngine {
ct_left: &mut Ciphertext,
ct_right: &Ciphertext,
) -> EngineResult<()> {
let modulus = (ct_right.degree.0 + 1) as u64;
let modulus_msg = ct_left.message_modulus.0 as u64;
let large_mod = modulus * modulus_msg;
let modulus_right = (ct_right.degree.0 + 1) as u64;
let modulus_left = ct_left.message_modulus.0 as u64;
self.unchecked_functional_bivariate_pbs_assign(server_key, ct_left, ct_right, |x| {
(((x % large_mod / modulus) % modulus_msg) < (x % modulus_msg)) as u64
(((x / modulus_right) % modulus_left) < (x % modulus_left)) as u64
})?;
ct_left.degree.0 = 1;
@@ -179,11 +176,10 @@ impl ShortintEngine {
ct_left: &mut Ciphertext,
ct_right: &Ciphertext,
) -> EngineResult<()> {
let modulus = (ct_right.degree.0 + 1) as u64;
let modulus_msg = ct_left.message_modulus.0 as u64;
let large_mod = modulus * modulus_msg;
let modulus_right = (ct_right.degree.0 + 1) as u64;
let modulus_left = ct_left.message_modulus.0 as u64;
self.unchecked_functional_bivariate_pbs_assign(server_key, ct_left, ct_right, |x| {
(((x % large_mod / modulus) % modulus_msg) <= (x % modulus_msg)) as u64
(((x / modulus_right) % modulus_left) <= (x % modulus_right)) as u64
})?;
ct_left.degree.0 = 1;
@@ -232,11 +228,10 @@ impl ShortintEngine {
ct_left: &mut Ciphertext,
ct_right: &Ciphertext,
) -> EngineResult<()> {
let modulus = (ct_right.degree.0 + 1) as u64;
let modulus_msg = ct_left.message_modulus.0 as u64;
let large_mod = modulus * modulus_msg;
let modulus_right = (ct_right.degree.0 + 1) as u64;
let modulus_left = ct_left.message_modulus.0 as u64;
self.unchecked_functional_bivariate_pbs_assign(server_key, ct_left, ct_right, |x| {
((((x % large_mod) / modulus) % modulus_msg) == (x % modulus_msg)) as u64
(((x / modulus_right) % modulus_left) == (x % modulus_left)) as u64
})?;
ct_left.degree.0 = 1;
Ok(())
@@ -309,11 +304,10 @@ impl ShortintEngine {
ct_left: &mut Ciphertext,
ct_right: &Ciphertext,
) -> EngineResult<()> {
let modulus = (ct_right.degree.0 + 1) as u64;
let modulus_msg = ct_left.message_modulus.0 as u64;
let large_mod = modulus * modulus_msg;
let modulus_right = (ct_right.degree.0 + 1) as u64;
let modulus_left = ct_left.message_modulus.0 as u64;
self.unchecked_functional_bivariate_pbs_assign(server_key, ct_left, ct_right, |x| {
((((x % large_mod) / modulus) % modulus_msg) != (x % modulus_msg)) as u64
(((x / modulus_right) % modulus_left) != (x % modulus_left)) as u64
})?;
ct_left.degree.0 = 1;
Ok(())

View File

@@ -484,10 +484,10 @@ impl ServerKey {
///
///```rust
/// use tfhe::shortint::gen_keys;
/// use tfhe::shortint::parameters::PARAM_MESSAGE_1_CARRY_1;
/// use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
///
/// // Generate the client key and the server key:
/// let (cks, sks) = gen_keys(PARAM_MESSAGE_1_CARRY_1);
/// let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);
///
/// let clear = 9;
///

View File

@@ -168,6 +168,7 @@ create_parametrized_test_bivariate_pbs_compliant!(
create_parametrized_test_bivariate_pbs_compliant!(
shortint_encrypt_with_message_modulus_smart_add_and_mul
);
create_parametrized_test_bivariate_pbs_compliant!(shortint_unchecked_less_or_equal_trivial);
/// test encryption and decryption with the LWE client key
fn shortint_encrypt_decrypt(param: Parameters) {
@@ -998,6 +999,36 @@ fn shortint_unchecked_less_or_equal(param: Parameters) {
}
}
/// test '<=' with the LWE server key
fn shortint_unchecked_less_or_equal_trivial(param: Parameters) {
let keys = KEY_CACHE.get_from_param(param);
let (cks, sks) = (keys.client_key(), keys.server_key());
//RNG
let mut rng = rand::thread_rng();
let modulus = cks.parameters.message_modulus.0 as u64;
for _ in 0..NB_TEST {
let clear_0 = rng.gen::<u64>() % modulus;
let clear_1 = rng.gen::<u64>() % modulus;
// encryption of an integer
let ctxt_0 = sks.create_trivial(clear_0);
// encryption of an integer
let ctxt_1 = sks.create_trivial(clear_1);
// add the two ciphertexts
let ct_res = sks.unchecked_less_or_equal(&ctxt_0, &ctxt_1);
// decryption of ct_res
let dec_res = cks.decrypt(&ct_res);
// assert
assert_eq!((clear_0 <= clear_1) as u64, dec_res);
}
}
/// test '<=' with the LWE server key
fn shortint_smart_less_or_equal(param: Parameters) {
let keys = KEY_CACHE.get_from_param(param);