diff --git a/docs/devdocs/Writing Smart Contracts/Gas-and-Banchmarks.md b/docs/devdocs/Writing Smart Contracts/Gas-and-Banchmarks.md
new file mode 100644
index 00000000..dd4e922f
--- /dev/null
+++ b/docs/devdocs/Writing Smart Contracts/Gas-and-Banchmarks.md
@@ -0,0 +1,359 @@
+# 🔥 Gas and Banchmarks
+
+This section will list the gas costs for every operation based on it's inputs.
+The gas prices are a subject to change based on usage and performance.
+
+:::tip
+The current gas limit for a tranasaction is set to be 50 million
+:::
+
+
+
+
+ FHE.sol function |
+ Input |
+ Time in Query (ms) |
+ Gas Units |
+
+
+
+
+ add |
+ euint8 |
+ 35 |
+ 7,315 |
+
+
+ euint16 |
+ 73 |
+ 15,275 |
+
+
+ euint32 |
+ 163 |
+ 34,067 |
+
+
+ asEuint |
+ inEuint |
+ 44 |
+ 9,196 |
+
+
+ euint |
+ 5 |
+ 1,045 |
+
+
+ uint |
+ 5 |
+ 1,045 |
+
+
+ sealOutput |
+ * |
+ 23 |
+ 2,507 |
+
+
+ decrypt |
+ * |
+ 18 |
+ 3,762 |
+
+
+ lte |
+ euint8 |
+ 18 |
+ 3,762 |
+
+
+ euint16 |
+ 29 |
+ 6,061 |
+
+
+ euint32 |
+ 43 |
+ 8,987 |
+
+
+ sbb |
+ euint8 |
+ 35 |
+ 7,315 |
+
+
+ euint16 |
+ 73 |
+ 15,275 |
+
+
+ euint32 |
+ 163 |
+ 34,067 |
+
+
+ mul |
+ euint8 |
+ 94 |
+ 19,646 |
+
+
+ euint16 |
+ 311 |
+ 64,999 |
+
+
+ euint32 |
+ 1127 |
+ 235,543 |
+
+
+ lt |
+ euint8 |
+ 22 |
+ 4,598 |
+
+
+ euint16 |
+ 36 |
+ 7,524 |
+
+
+ euint32 |
+ 60 |
+ 12,540 |
+
+
+ select |
+ euint8 |
+ 214 |
+ 44,726 |
+
+
+ euint16 |
+ 316 |
+ 66,044 |
+
+
+ euint32 |
+ 549 |
+ 114,741 |
+
+
+ require |
+ * |
+ 65 |
+ 13,585 |
+
+
+ div |
+ euint8 |
+ 447 |
+ 93,423 |
+
+
+ euint16 |
+ 1310 |
+ 273,790 |
+
+
+ euint32 |
+ 4800 |
+ 1,003,200 |
+
+
+ gt |
+ euint8 |
+ 21 |
+ 4,389 |
+
+
+ euint16 |
+ 29 |
+ 6,061 |
+
+
+ euint32 |
+ 45 |
+ 9,405 |
+
+
+ gte |
+ euint8 |
+ 21 |
+ 4,389 |
+
+
+ euint16 |
+ 29 |
+ 6,061 |
+
+
+ euint32 |
+ 45 |
+ 9,405 |
+
+
+ rem |
+ euint8 |
+ 447 |
+ 93,423 |
+
+
+ euint16 |
+ 1310 |
+ 273,790 |
+
+
+ euint32 |
+ 4800 |
+ 1,003,200 |
+
+
+ or |
+ euint8 |
+ 13 |
+ 2,717 |
+
+
+ euint16 |
+ 21 |
+ 4,389 |
+
+
+ euint32 |
+ 38 |
+ 7,942 |
+
+
+ xor |
+ euint8 |
+ 13 |
+ 2,717 |
+
+
+ euint16 |
+ 21 |
+ 4,389 |
+
+
+ euint32 |
+ 38 |
+ 7,942 |
+
+
+ eq |
+ euint8 |
+ 18 |
+ 3,762 |
+
+
+ euint16 |
+ 25 |
+ 5,225 |
+
+
+ euint32 |
+ 50 |
+ 10,450 |
+
+
+ ne |
+ euint8 |
+ 18 |
+ 3,762 |
+
+
+ euint16 |
+ 25 |
+ 5,225 |
+
+
+ euint32 |
+ 50 |
+ 10,450 |
+
+
+ min |
+ euint8 |
+ 41 |
+ 8,569 |
+
+
+ euint16 |
+ 75 |
+ 15,675 |
+
+
+ euint32 |
+ 135 |
+ 28,215 |
+
+
+ max |
+ euint8 |
+ 41 |
+ 8,569 |
+
+
+ euint16 |
+ 75 |
+ 15,675 |
+
+
+ euint32 |
+ 135 |
+ 28,215 |
+
+
+ shl |
+ euint8 |
+ 82 |
+ 17,138 |
+
+
+ euint16 |
+ 190 |
+ 39,710 |
+
+
+ euint32 |
+ 422 |
+ 88,198 |
+
+
+ shr |
+ euint8 |
+ 82 |
+ 17,138 |
+
+
+ euint16 |
+ 190 |
+ 39,710 |
+
+
+ euint32 |
+ 422 |
+ 88,198 |
+
+
+ not |
+ euint8 |
+ 12 |
+ 2,508 |
+
+
+ euint16 |
+ 22 |
+ 4,598 |
+
+
+ euint32 |
+ 36 |
+ 7,524 |
+
+
+
diff --git a/docs/devdocs/Writing Smart Contracts/Types-and-Operators.md b/docs/devdocs/Writing Smart Contracts/Types-and-Operators.md
index 4e5a588a..5a96c0df 100644
--- a/docs/devdocs/Writing Smart Contracts/Types-and-Operators.md
+++ b/docs/devdocs/Writing Smart Contracts/Types-and-Operators.md
@@ -19,7 +19,7 @@ These encrypted integers behave as much as possible as Solidity's integer types.
In the back-end, encrypted integers are FHE ciphertexts. The library abstracts away the ciphertexts and presents pointers to ciphertexts, or ciphertext handles, to the smart contract developer. The `euint` types are _wrappers_ over these handles.
| name | Bit Size | Usage |
-|-----------|----------|---------|
+| --------- | -------- | ------- |
| euint8 | 8 | Compute |
| euint16 | 16 | Compute |
| euint32 | 32 | Compute |
@@ -32,6 +32,7 @@ In the back-end, encrypted integers are FHE ciphertexts. The library abstracts a
There are three ways to perform operations with FHE.sol:
### Using Direct Function Calls
+
Direct function calls are the most straightforward way to perform operations with FHE.sol. For example, if you want to add two encrypted 8-bit integers (euint8), you can do so as follows:
```javascript
@@ -41,6 +42,7 @@ euint8 result = FHE.add(lhs, rhs);
Here, lhs and rhs are your euint8 variables, and result will store the outcome of the addition.
### Using Library Bindings
+
FHE.sol also provides library bindings, allowing for a more natural syntax. To use this, you first need to include the library for your specific data type. For euint8, the usage would look like this:
```javascript
@@ -51,9 +53,9 @@ In this example, lhs.add(rhs) performs the addition, using the library function
### Utilizing Operator Overloading
-For an even more intuitive approach, FHE.sol supports operator overloading. This means you can use standard arithmetic operators like +, -, *, etc., directly on encrypted types. Here's how you can use it for adding two euint8 values:
+For an even more intuitive approach, FHE.sol supports operator overloading. This means you can use standard arithmetic operators like +, -, \*, etc., directly on encrypted types. Here's how you can use it for adding two euint8 values:
-```
+```javascript
euint8 result = lhs + rhs;
```
@@ -73,19 +75,24 @@ The `ebool` type is not a real boolean type. It is implemented as a `euint8`
## Supported Operations
+:::tip
+A documented documentation of each and every function in FHE.sol (including inputs and outputs) can be found in [FHE.sol](../Solidity%20API/FHE.md)
+:::
+
All operations supported by FHE.sol are listed in the table below:
Note that all functions are supported in both direct function calls and library bindings. However, operator overloading is only supported for the operations listed in the table (solidity please support operator overloading for boolean return types!).
| name | FHE.sol function | Operator |
-|-----------------------|------------------|----------|
+| --------------------- | ---------------- | -------- |
| Addition | add | + |
| Subtraction | sub | - |
-| Multiplication | mul | * |
-| Division | div | / |
+| Multiplication | mul | \* |
| Bitwise And | and | & |
| Bitwise Or | or | \| |
| Bitwise Xor | xor | ^ |
+| Division | div | / |
+| Reminder | rem | % |
| Shift Right | shr | >> |
| Shift Left | shl | << |
| Equal | eq | n/a |
@@ -98,8 +105,19 @@ Note that all functions are supported in both direct function calls and library
| Max | max | n/a |
| Negative | neg | n/a |
| Not | not | n/a |
+| Require | req | n/a |
+| Decrypt | decrypt | n/a |
+| Seal Output | sealOutput | n/a |
:::danger
At the moment it is not possible to do `ebool result = (lhs == rhs)` and others that return a boolean result. This is because FHE.sol expects a `ebool`, while Solidity only allows overloading to return a regular boolean.
Instead, we recommend `ebool result = lhs.eq(rhs)`.
-:::
\ No newline at end of file
+:::
+
+:::danger
+Using require and decrypt in a TX is dangerous as it can break the confidentiality of the data. Please refer to [Useful-Tips](./Useful-Tips.md) to read some more
+:::
+
+:::tip
+Division and Reminder of devisions by `0` will output with an encrypted representation of the maximal value of the uint that is used (Ex. encrypted 255 for euint8)
+:::
diff --git a/docs/devdocs/Writing Smart Contracts/Useful-Tips.md b/docs/devdocs/Writing Smart Contracts/Useful-Tips.md
index 0b6c03fc..c81c24e0 100644
--- a/docs/devdocs/Writing Smart Contracts/Useful-Tips.md
+++ b/docs/devdocs/Writing Smart Contracts/Useful-Tips.md
@@ -1,4 +1,4 @@
-# 🔥 Useful Tips
+# ℹ️ Useful Tips
This section will list some useful tips and good practices for you to be able to use them.
@@ -21,9 +21,30 @@ In order to understand how we will first need to understand that FHE encryption
Now that we know that, we can add 0 (cryptographically with FHE.add) to all of those tallies that shouldn't be changed and they will be changed in the DB!
-## FHE.req() in TXs
+## FHE.req()
-All the operations are supported both in TXs and in Queries. That being said we strongly advise to think twice before you use those operations inside a TX. FHE.req() is actually exposing the value of your encrypted data. Assuming we will send the transaction and monitor the gas usage we can probably identify whether the FHE.req() condition met or not and understand a lot about what the encrypted values represent.
+All the operations are supported both in TXs and in Queries. That being said we strongly advise to think twice before you use those operations inside a TX. `FHE.req` is actually exposing the value of your encrypted data. Assuming we will send the transaction and monitor the gas usage we can probably identify whether the `FHE.req` condition met or not and understand a lot about what the encrypted values represent.
+Example:
+
+```javascript
+function f(euint8 a, euint8 b) public {
+ FHE.req(a.eq(b));
+ // Do some heavy logic
+}
+```
+
+In this case, if `a` and `b` won't be equal it will fail immediately and take less gas than the case when `a` and `b` are equal which means that one who checks the gas can easily know the equality of `a` and `b` it won't leak their values but it will leak confidential data.
+The rule of thumb that we are suggesting is to use `FHE.req` only in `view` functions while the logic of `FHE.req` in txs can be implemented using `FHE.select`
+
+## FHE.decrypt()
+
+Generally speaking, the idea of Fhenix and having FHE in place is the ability to have your values encrypted throughout the whole lifetime of the data (since you can operate on encrypted data). When using `FHE.decrypt` you should always consider the following:
+a. On mainnet (and future testnet versions) the decryption process will be done on a threshold network and the operation might not be fully deterministic (network issues for example)
+b. Assuming malicious node runner have DMA (direct memory access) or any other way to read the process' memory he can see what is the decrypted value while it is being executed and use MEV techniques.
+
+We recommended a rule of thumb to when to decrypt:
+a. In view functions
+b. In TXs when you are 100% confident that the data is not confidential anymore (For example in poker game when the transaction is a roundup transaction so you can reveal the cards without being afraid of data leakage)
## Performance and Gas Usage
@@ -32,7 +53,7 @@ Currently, we support many FHE operations. Some of them might take a lot of time
When writing FHE code we encourage you to use the operations wisely and choose what operation should be used.
Example: Instead of `ENCRYPTED_UINT_32 * FHE.asEuint32(2)` you can use `FHE.shl(ENCRYPTED_UINT_32, FHE.asEuint32(1))` in some cases `FHE.div(ENCRYPTED_UINT_32, FHE.asEuint32(2))` can be replaced by `FHE.shr(ENCRYPTED_UINT_32, FHE.asEuint32(1))`
-For more detailed benchmarks please refer to: TBD
+For more detailed benchmarks please refer to: [Gas-and-Banchmarks](./Gas-and-Banchmarks)
## Randomness