This document explains a feature to facilitate debugging.
Starting from TFHE-rs 0.5, trivial ciphertexts introduce a new feature to facilitate debugging. This feature supports a debugger, print statements, and faster execution, significantly reducing waiting time and enhancing the development pace of FHE applications.
Trivial ciphertexts are not secure. An application released/deployed in production must never receive trivial ciphertext from a client.
To use this feature, simply call your circuits/functions with trivially encrypted values that are created using encrypt_trivial
(instead of real encryptions that are created using encrypt
):
This example is going to print:
If any input to mul_all
is not a trivial ciphertexts, the computations will be done 100% in FHE, and the program will output:
Using trivial encryptions as input, the example runs in 980 ms on a standard 12-core laptop, compared to 7.5 seconds on a 128-core machine using real encryptions.
This document explains how to use the PBS statistics feature in TFHE-rs' shortint API to assess the overall computational intensity in FHE applications.
The shortint
API now includes a global counter to track the number of Programmable Bootstrapping (PBS) executed with the pbs-stats
feature. This feature enables precise tracking of PBS executions in a circuit. It helps to estimate the overall compute intensity of FHE code using either the shortint
, integer,
or High-Level APIs.
To know how many PBSes were executed, call get_pbs_count
. To reset the PBS count, call reset_pbs_count
. You can combine two functions to understand how many PBSes were executed in each part of your code.
When combined with the debug mode
, this feature allows for quick estimations during iterations on the FHE code.
Here is an example of how to use the PBS counter:
This document serves as a practical reference for implementing generic functions in Rust that use operators across mixed references and values. The following explanations help you to understand the trait bounds necessary to handle such operations.
Operators such as +
, *
, >>,
and so on are tied to traits in std:::ops
. For instance, the +
operator corresponds to std::ops::Add
. When writing a generic function that uses the +
operator, you need to specify std::ops::Add
as a trait bound.
The trait bound varies slightly depending on whether the left-hand side / right-hand side is an owned value or a reference. The following table shows the different scenarios:
T $op T
T: $Op<T, Output=T>
T $op &T
T: for<'a> $Op<&'a T, Output=T>
&T $op T
for<'a> &'a T: $Op<T, Output=T>
&T $op &T
for<'a> &'a T: $Op<&'a T, Output=T>
The for<'a>
syntax refers to the Higher-Rank Trait Bounds(HRTB).
Using generic functions allows for clearer input handling, which simplifies the debugging.