Integers in Concrete are encrypted and processed according to a set of cryptographic parameters. By default, multiple sets of such parameters are selected by the Concrete Optimizer. This might not be the best approach for every use case, and there is the option to use mono parameters instead.
When multi parameters are enabled, a different set of parameters are selected for each bit-width in the circuit, which results in:
Faster execution (generally).
Slower key generation.
Larger keys.
Larger memory usage during execution.
To disable it, you can use parameter_selection_strategy=fhe.ParameterSelectionStrategy.MONO
configuration option.
When enabled, you can select the level of circuit partitioning, with multi_parameter_strategy in configuration.
Each integer in the circuit has a certain bit-width, which is determined by the inputset. These bit-widths can be observed when graphs are printed:
However, it's not possible to add 3-bit and 4-bit numbers together because their encoding is different:
The result of such an addition is a 5-bit number, which also has a different encoding:
Because of these encoding differences, we perform a graph processing step called bit-width assignment, which takes the graph and updates the bit-widths to be compatible with FHE.
After this graph processing step, the graph would look like:
Most operations cannot change the encoding, which means that the input and output bit-widths need to be the same. However, there is an operation which can change the encoding: the table lookup operation.
Let's say you have this graph:
This is the graph for (x**2) + y
where x
is 2-bits and y
is 5-bits. If the table lookup operation wasn't able to change the encoding, we'd need to make everything 6-bits. However, since the encoding can be changed, the bit-widths can be assigned like so:
In this case, we kept x
as 2-bits, but set the table lookup result and y
to be 6-bits, so that the addition can be performed.
This style of bit-width assignment is called multi-precision, and it is enabled by default. To disable it and use a single precision across the circuit, you can use the single_precision=True
configuration option.