mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-11 15:48:20 -05:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75d7865b77 | ||
|
|
343e0f1613 | ||
|
|
7be5aedc07 | ||
|
|
155ab13295 | ||
|
|
049e3518a7 | ||
|
|
9fff450f47 | ||
|
|
f1ebadf73d | ||
|
|
61b6db394e | ||
|
|
e4e9cc8489 | ||
|
|
7e6facc08c | ||
|
|
0bb12ab9ea |
2
.github/workflows/m1_tests.yml
vendored
2
.github/workflows/m1_tests.yml
vendored
@@ -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
56
LICENSE
@@ -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.
|
||||
|
||||
4
Makefile
4
Makefile
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"]
|
||||
|
||||
56
tfhe/LICENSE
56
tfhe/LICENSE
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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;
|
||||
///
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user