mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-08 19:44:57 -05:00
docs: last update from Gitbook
This commit is contained in:
192
docs/getting-started/compatibility.md
Normal file
192
docs/getting-started/compatibility.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Compatibility
|
||||
|
||||
## Supported operations
|
||||
|
||||
Here are the operations you can use inside the function you are compiling.
|
||||
|
||||
{% hint style="info" %}
|
||||
Some of these operations are not supported between two encrypted values. A detailed error will be raised if you try to do something that is not supported.
|
||||
{% endhint %}
|
||||
|
||||
### Supported Python operators
|
||||
|
||||
* [\_\_abs\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_abs\_\_)
|
||||
* [\_\_add\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_add\_\_)
|
||||
* [\_\_and\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_and\_\_)
|
||||
* [\_\_eq\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_eq\_\_)
|
||||
* [\_\_floordiv\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_floordiv\_\_)
|
||||
* [\_\_ge\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_ge\_\_)
|
||||
* [\_\_getitem\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_getitem\_\_)
|
||||
* [\_\_gt\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_gt\_\_)
|
||||
* [\_\_invert\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_invert\_\_)
|
||||
* [\_\_le\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_le\_\_)
|
||||
* [\_\_lshift\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_lshift\_\_)
|
||||
* [\_\_lt\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_lt\_\_)
|
||||
* [\_\_matmul\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_matmul\_\_)
|
||||
* [\_\_mod\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_mod\_\_)
|
||||
* [\_\_mul\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_mul\_\_)
|
||||
* [\_\_ne\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_ne\_\_)
|
||||
* [\_\_neg\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_neg\_\_)
|
||||
* [\_\_or\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_or\_\_)
|
||||
* [\_\_pos\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_pos\_\_)
|
||||
* [\_\_pow\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_pow\_\_)
|
||||
* [\_\_radd\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_radd\_\_)
|
||||
* [\_\_rand\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rand\_\_)
|
||||
* [\_\_rfloordiv\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rfloordiv\_\_)
|
||||
* [\_\_rlshift\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rlshift\_\_)
|
||||
* [\_\_rmatmul\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rmatmul\_\_)
|
||||
* [\_\_rmod\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rmod\_\_)
|
||||
* [\_\_rmul\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rmul\_\_)
|
||||
* [\_\_ror\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_ror\_\_)
|
||||
* [\_\_round\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_round\_\_)
|
||||
* [\_\_rpow\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rpow\_\_)
|
||||
* [\_\_rrshift\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rrshift\_\_)
|
||||
* [\_\_rshift\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rshift\_\_)
|
||||
* [\_\_rsub\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rsub\_\_)
|
||||
* [\_\_rtruediv\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rtruediv\_\_)
|
||||
* [\_\_rxor\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_rxor\_\_)
|
||||
* [\_\_sub\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_sub\_\_)
|
||||
* [\_\_truediv\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_truediv\_\_)
|
||||
* [\_\_xor\_\_](https://docs.python.org/3/reference/datamodel.html#object.\_\_xor\_\_)
|
||||
|
||||
### Supported NumPy functions
|
||||
|
||||
<!--- gen_supported_ufuncs.py: inject supported operations [BEGIN] -->
|
||||
<!--- do not edit, auto generated part by `python3 gen_supported_ufuncs.py` in docker -->
|
||||
* [np.absolute](https://numpy.org/doc/stable/reference/generated/numpy.absolute.html)
|
||||
* [np.add](https://numpy.org/doc/stable/reference/generated/numpy.add.html)
|
||||
* [np.arccos](https://numpy.org/doc/stable/reference/generated/numpy.arccos.html)
|
||||
* [np.arccosh](https://numpy.org/doc/stable/reference/generated/numpy.arccosh.html)
|
||||
* [np.arcsin](https://numpy.org/doc/stable/reference/generated/numpy.arcsin.html)
|
||||
* [np.arcsinh](https://numpy.org/doc/stable/reference/generated/numpy.arcsinh.html)
|
||||
* [np.arctan](https://numpy.org/doc/stable/reference/generated/numpy.arctan.html)
|
||||
* [np.arctan2](https://numpy.org/doc/stable/reference/generated/numpy.arctan2.html)
|
||||
* [np.arctanh](https://numpy.org/doc/stable/reference/generated/numpy.arctanh.html)
|
||||
* [np.around](https://numpy.org/doc/stable/reference/generated/numpy.around.html)
|
||||
* [np.bitwise\_and](https://numpy.org/doc/stable/reference/generated/numpy.bitwise\_and.html)
|
||||
* [np.bitwise\_or](https://numpy.org/doc/stable/reference/generated/numpy.bitwise\_or.html)
|
||||
* [np.bitwise\_xor](https://numpy.org/doc/stable/reference/generated/numpy.bitwise\_xor.html)
|
||||
* [np.cbrt](https://numpy.org/doc/stable/reference/generated/numpy.cbrt.html)
|
||||
* [np.ceil](https://numpy.org/doc/stable/reference/generated/numpy.ceil.html)
|
||||
* [np.clip](https://numpy.org/doc/stable/reference/generated/numpy.clip.html)
|
||||
* [np.concatenate](https://numpy.org/doc/stable/reference/generated/numpy.concatenate.html)
|
||||
* [np.copysign](https://numpy.org/doc/stable/reference/generated/numpy.copysign.html)
|
||||
* [np.cos](https://numpy.org/doc/stable/reference/generated/numpy.cos.html)
|
||||
* [np.cosh](https://numpy.org/doc/stable/reference/generated/numpy.cosh.html)
|
||||
* [np.deg2rad](https://numpy.org/doc/stable/reference/generated/numpy.deg2rad.html)
|
||||
* [np.degrees](https://numpy.org/doc/stable/reference/generated/numpy.degrees.html)
|
||||
* [np.dot](https://numpy.org/doc/stable/reference/generated/numpy.dot.html)
|
||||
* [np.equal](https://numpy.org/doc/stable/reference/generated/numpy.equal.html)
|
||||
* [np.exp](https://numpy.org/doc/stable/reference/generated/numpy.exp.html)
|
||||
* [np.exp2](https://numpy.org/doc/stable/reference/generated/numpy.exp2.html)
|
||||
* [np.expm1](https://numpy.org/doc/stable/reference/generated/numpy.expm1.html)
|
||||
* [np.fabs](https://numpy.org/doc/stable/reference/generated/numpy.fabs.html)
|
||||
* [np.float\_power](https://numpy.org/doc/stable/reference/generated/numpy.float\_power.html)
|
||||
* [np.floor](https://numpy.org/doc/stable/reference/generated/numpy.floor.html)
|
||||
* [np.floor\_divide](https://numpy.org/doc/stable/reference/generated/numpy.floor\_divide.html)
|
||||
* [np.fmax](https://numpy.org/doc/stable/reference/generated/numpy.fmax.html)
|
||||
* [np.fmin](https://numpy.org/doc/stable/reference/generated/numpy.fmin.html)
|
||||
* [np.fmod](https://numpy.org/doc/stable/reference/generated/numpy.fmod.html)
|
||||
* [np.gcd](https://numpy.org/doc/stable/reference/generated/numpy.gcd.html)
|
||||
* [np.greater](https://numpy.org/doc/stable/reference/generated/numpy.greater.html)
|
||||
* [np.greater\_equal](https://numpy.org/doc/stable/reference/generated/numpy.greater\_equal.html)
|
||||
* [np.heaviside](https://numpy.org/doc/stable/reference/generated/numpy.heaviside.html)
|
||||
* [np.hypot](https://numpy.org/doc/stable/reference/generated/numpy.hypot.html)
|
||||
* [np.invert](https://numpy.org/doc/stable/reference/generated/numpy.invert.html)
|
||||
* [np.isfinite](https://numpy.org/doc/stable/reference/generated/numpy.isfinite.html)
|
||||
* [np.isinf](https://numpy.org/doc/stable/reference/generated/numpy.isinf.html)
|
||||
* [np.isnan](https://numpy.org/doc/stable/reference/generated/numpy.isnan.html)
|
||||
* [np.lcm](https://numpy.org/doc/stable/reference/generated/numpy.lcm.html)
|
||||
* [np.ldexp](https://numpy.org/doc/stable/reference/generated/numpy.ldexp.html)
|
||||
* [np.left\_shift](https://numpy.org/doc/stable/reference/generated/numpy.left\_shift.html)
|
||||
* [np.less](https://numpy.org/doc/stable/reference/generated/numpy.less.html)
|
||||
* [np.less\_equal](https://numpy.org/doc/stable/reference/generated/numpy.less\_equal.html)
|
||||
* [np.log](https://numpy.org/doc/stable/reference/generated/numpy.log.html)
|
||||
* [np.log10](https://numpy.org/doc/stable/reference/generated/numpy.log10.html)
|
||||
* [np.log1p](https://numpy.org/doc/stable/reference/generated/numpy.log1p.html)
|
||||
* [np.log2](https://numpy.org/doc/stable/reference/generated/numpy.log2.html)
|
||||
* [np.logaddexp](https://numpy.org/doc/stable/reference/generated/numpy.logaddexp.html)
|
||||
* [np.logaddexp2](https://numpy.org/doc/stable/reference/generated/numpy.logaddexp2.html)
|
||||
* [np.logical\_and](https://numpy.org/doc/stable/reference/generated/numpy.logical\_and.html)
|
||||
* [np.logical\_not](https://numpy.org/doc/stable/reference/generated/numpy.logical\_not.html)
|
||||
* [np.logical\_or](https://numpy.org/doc/stable/reference/generated/numpy.logical\_or.html)
|
||||
* [np.logical\_xor](https://numpy.org/doc/stable/reference/generated/numpy.logical\_xor.html)
|
||||
* [np.matmul](https://numpy.org/doc/stable/reference/generated/numpy.matmul.html)
|
||||
* [np.maximum](https://numpy.org/doc/stable/reference/generated/numpy.maximum.html)
|
||||
* [np.minimum](https://numpy.org/doc/stable/reference/generated/numpy.minimum.html)
|
||||
* [np.multiply](https://numpy.org/doc/stable/reference/generated/numpy.multiply.html)
|
||||
* [np.negative](https://numpy.org/doc/stable/reference/generated/numpy.negative.html)
|
||||
* [np.nextafter](https://numpy.org/doc/stable/reference/generated/numpy.nextafter.html)
|
||||
* [np.not\_equal](https://numpy.org/doc/stable/reference/generated/numpy.not\_equal.html)
|
||||
* [np.ones\_like](https://numpy.org/doc/stable/reference/generated/numpy.ones\_like.html)
|
||||
* [np.positive](https://numpy.org/doc/stable/reference/generated/numpy.positive.html)
|
||||
* [np.power](https://numpy.org/doc/stable/reference/generated/numpy.power.html)
|
||||
* [np.rad2deg](https://numpy.org/doc/stable/reference/generated/numpy.rad2deg.html)
|
||||
* [np.radians](https://numpy.org/doc/stable/reference/generated/numpy.radians.html)
|
||||
* [np.reciprocal](https://numpy.org/doc/stable/reference/generated/numpy.reciprocal.html)
|
||||
* [np.remainder](https://numpy.org/doc/stable/reference/generated/numpy.remainder.html)
|
||||
* [np.reshape](https://numpy.org/doc/stable/reference/generated/numpy.reshape.html)
|
||||
* [np.right\_shift](https://numpy.org/doc/stable/reference/generated/numpy.right\_shift.html)
|
||||
* [np.rint](https://numpy.org/doc/stable/reference/generated/numpy.rint.html)
|
||||
* [np.round\_](https://numpy.org/doc/stable/reference/generated/numpy.round\_.html)
|
||||
* [np.sign](https://numpy.org/doc/stable/reference/generated/numpy.sign.html)
|
||||
* [np.signbit](https://numpy.org/doc/stable/reference/generated/numpy.signbit.html)
|
||||
* [np.sin](https://numpy.org/doc/stable/reference/generated/numpy.sin.html)
|
||||
* [np.sinh](https://numpy.org/doc/stable/reference/generated/numpy.sinh.html)
|
||||
* [np.spacing](https://numpy.org/doc/stable/reference/generated/numpy.spacing.html)
|
||||
* [np.sqrt](https://numpy.org/doc/stable/reference/generated/numpy.sqrt.html)
|
||||
* [np.square](https://numpy.org/doc/stable/reference/generated/numpy.square.html)
|
||||
* [np.subtract](https://numpy.org/doc/stable/reference/generated/numpy.subtract.html)
|
||||
* [np.sum](https://numpy.org/doc/stable/reference/generated/numpy.sum.html)
|
||||
* [np.tan](https://numpy.org/doc/stable/reference/generated/numpy.tan.html)
|
||||
* [np.tanh](https://numpy.org/doc/stable/reference/generated/numpy.tanh.html)
|
||||
* [np.transpose](https://numpy.org/doc/stable/reference/generated/numpy.transpose.html)
|
||||
* [np.true\_divide](https://numpy.org/doc/stable/reference/generated/numpy.true\_divide.html)
|
||||
* [np.trunc](https://numpy.org/doc/stable/reference/generated/numpy.trunc.html)
|
||||
* [np.where](https://numpy.org/doc/stable/reference/generated/numpy.where.html)
|
||||
* [np.zeros\_like](https://numpy.org/doc/stable/reference/generated/numpy.zeros\_like.html)
|
||||
<!--- gen_supported_ufuncs.py: inject supported operations [END] -->
|
||||
|
||||
### Supported `ndarray` methods
|
||||
|
||||
* [np.ndarray.astype](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.astype.html)
|
||||
* [np.ndarray.clip](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.clip.html)
|
||||
* [np.ndarray.dot](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.dot.html)
|
||||
* [np.ndarray.flatten](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.flatten.html)
|
||||
* [np.ndarray.reshape](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.reshape.html)
|
||||
* [np.ndarray.transpose](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.transpose.html)
|
||||
|
||||
### Supported `ndarray` properties
|
||||
|
||||
* [np.ndarray.shape](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.shape.html)
|
||||
* [np.ndarray.ndim](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.ndim.html)
|
||||
* [np.ndarray.size](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.size.html)
|
||||
* [np.ndarray.T](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.T.html)
|
||||
|
||||
## Limitations
|
||||
|
||||
### Operational constraints
|
||||
|
||||
Some Python control flow statements are not supported. For example, you cannot have an `if` statement or a `while` statement for which the condition depends on an encrypted value. However, such statements are supported with constant values (e.g., `for i in range(SOME_CONSTANT)`, `if os.environ.get("SOME_FEATURE") == "ON":`).
|
||||
|
||||
Another constraint is that you cannot have floating-point inputs or floating-point outputs. You can have floating-point intermediate values as long as they can be converted to an integer Table Lookup (e.g., `(60 * np.sin(x)).astype(np.int64)`).
|
||||
|
||||
### Bit width constraints
|
||||
|
||||
There is a limit on the bit width of encrypted values. We are constantly working on increasing this bit width. If you go above this limit, you will get an error.
|
||||
|
||||
### Computation constraints
|
||||
|
||||
One of the most common operations in **Concrete Numpy** is `Table Lookups` (TLUs). TLUs are performed with an FHE operation called `Programmable Bootstrapping` (PBS). PBSes have a certain probability of error, which, when triggered, result in inaccurate results.
|
||||
|
||||
Let's say you have the table:
|
||||
|
||||
```python
|
||||
[1, 4, 9, 16, 25, 36, 49, 64]
|
||||
```
|
||||
|
||||
And you performed a table lookup using `4`, The result you should get is `16`, but because of the possibility of error, you can sometimes get `9` or `25`.
|
||||
|
||||
{% hint style="info" %}
|
||||
The probability of this error can be configured through the `p_error` configuration option, which has the default value of `0.000063342483999973` (i.e., probability of success is `99.993`%). Keep in mind that changing it could affect compilation and key generation times.
|
||||
{% endhint %}
|
||||
55
docs/getting-started/installing.md
Normal file
55
docs/getting-started/installing.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Installation
|
||||
|
||||
**Concrete Numpy** is natively supported on Linux and macOS for Python 3.8 and 3.9, but if you have Docker support in your platform, you can use the docker image to use **Concrete Numpy**.
|
||||
|
||||
## Using PyPI
|
||||
|
||||
You can install **Concrete Numpy** from PyPI:
|
||||
|
||||
```shell
|
||||
pip install concrete-numpy
|
||||
```
|
||||
|
||||
{% hint style="warning" %}
|
||||
Apple silicon users must use docker installation (explained below) as there is no ARM version of some of our dependencies for the time being.
|
||||
{% endhint %}
|
||||
|
||||
You can install the extra python dependencies for drawing circuits:
|
||||
|
||||
```shell
|
||||
pip install concrete-numpy[full]
|
||||
```
|
||||
|
||||
{% hint style="info" %}
|
||||
**Concrete Numpy** depends on `pygraphviz` for drawing, which requires `graphviz` packages to be installed on your system (see [pygraphviz installation documentation](https://pygraphviz.github.io/documentation/stable/install.html)).
|
||||
{% endhint %}
|
||||
|
||||
## Using Docker
|
||||
|
||||
You can also get the **Concrete Numpy** docker image:
|
||||
|
||||
```shell
|
||||
docker pull zamafhe/concrete-numpy:v0.6.0
|
||||
```
|
||||
|
||||
### Starting Jupyter server
|
||||
|
||||
By default, the entry point of the **Concrete Numpy** docker image is a jupyter server that you can access from your browser:
|
||||
|
||||
```shell
|
||||
docker run --rm -it -p 8888:8888 zamafhe/concrete-numpy:latest
|
||||
```
|
||||
|
||||
To save notebooks on host, you can use a local volume:
|
||||
|
||||
```shell
|
||||
docker run --rm -it -p 8888:8888 -v /path/to/notebooks:/data zamafhe/concrete-numpy:latest
|
||||
```
|
||||
|
||||
### Starting Bash session
|
||||
|
||||
Alternatively, you can launch a Bash session:
|
||||
|
||||
```shell
|
||||
docker run --rm -it zamafhe/concrete-numpy:latest /bin/bash
|
||||
```
|
||||
86
docs/getting-started/quick_start.md
Normal file
86
docs/getting-started/quick_start.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Quick Start
|
||||
|
||||
To compute on encrypted data, you first need to define the function that you want to compute, then compile it into a Concrete Numpy `Circuit`, which you can use to perform homomorphic evaluation.
|
||||
|
||||
Here is the full example that we will walk through:
|
||||
|
||||
```python
|
||||
import concrete.numpy as cnp
|
||||
|
||||
def add(x, y):
|
||||
return x + y
|
||||
|
||||
compiler = cnp.Compiler(add, {"x": "encrypted", "y": "clear"})
|
||||
|
||||
inputset = [(2, 3), (0, 0), (1, 6), (7, 7), (7, 1)]
|
||||
circuit = compiler.compile(inputset)
|
||||
|
||||
x = 4
|
||||
y = 4
|
||||
|
||||
clear_evaluation = add(x, y)
|
||||
homomorphic_evaluation = circuit.encrypt_run_decrypt(x, y)
|
||||
|
||||
print(x, "+", y, "=", clear_evaluation, "=", homomorphic_evaluation)
|
||||
```
|
||||
|
||||
## Importing the library
|
||||
|
||||
Everything you need to perform homomorphic evaluation is included in a single module:
|
||||
|
||||
<!--pytest-codeblocks:skip-->
|
||||
```python
|
||||
import concrete.numpy as cnp
|
||||
```
|
||||
|
||||
## Defining the function to compile
|
||||
|
||||
In this example, we will compile a simple addition function:
|
||||
|
||||
<!--pytest-codeblocks:skip-->
|
||||
```python
|
||||
def add(x, y):
|
||||
return x + y
|
||||
```
|
||||
|
||||
## Creating a compiler
|
||||
|
||||
To compile the function, you need to create a `Compiler` by specifying the function to compile and encryption status of its inputs:
|
||||
|
||||
<!--pytest-codeblocks:skip-->
|
||||
```python
|
||||
compiler = cnp.Compiler(add, {"x": "encrypted", "y": "clear"})
|
||||
```
|
||||
|
||||
## Defining an inputset
|
||||
|
||||
An inputset is a collection representing the typical inputs to the function. It is used to determine the bit widths and shapes of the variables within the function.
|
||||
|
||||
It should be an iterable, yielding tuples of the same length as the number of arguments of the function being compiled:
|
||||
|
||||
<!--pytest-codeblocks:skip-->
|
||||
```python
|
||||
inputset = [(2, 3), (0, 0), (1, 6), (7, 7), (7, 1)]
|
||||
```
|
||||
|
||||
## Compiling the function
|
||||
|
||||
You can use the `compile` method of a `Compiler` class with an inputset to perform the compilation and get the resulting circuit back:
|
||||
|
||||
<!--pytest-codeblocks:skip-->
|
||||
```python
|
||||
circuit = compiler.compile(inputset)
|
||||
```
|
||||
|
||||
## Performing homomorphic evaluation
|
||||
|
||||
You can use the `encrypt_run_decrypt` method of a `Circuit` class to perform homomorphic evaluation:
|
||||
|
||||
<!--pytest-codeblocks:skip-->
|
||||
```python
|
||||
homomorphic_evaluation = circuit.encrypt_run_decrypt(4, 4)
|
||||
```
|
||||
|
||||
{% hint style="info" %}
|
||||
`circuit.encrypt_run_decrypt(*args)` is just a convenient way to do everything at once. It is implemented as `circuit.decrypt(circuit.run(circuit.encrypt(*args)))`.
|
||||
{% endhint %}
|
||||
Reference in New Issue
Block a user