Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .github/workflows/deploy-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Deploy preview to GitHub Pages

on:
pull_request:

permissions:
contents: write

jobs:
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write

env:
PR_PATH: pull/${{github.event.number}}
DOMAIN: docs.fhenix.zone
steps:
- name: Comment on PR
uses: hasura/comment-progress@v2.2.0
if: github.ref != 'refs/heads/main'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
number: ${{ github.event.number }}
id: deploy-preview
message: "Starting deployment of preview ⏳..."

- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build website
run: yarn build

- name: Set base URL for preview
if: github.ref != 'refs/heads/main'
run: echo "BASE_URL=https://${{ env.DOMAIN }}/${{ github.event.repository.name }}/${{ env.PR_PATH}}/" >> $GITHUB_ENV

# Popular action to deploy to GitHub Pages:
# Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# Build output to publish to the `gh-pages` branch:
publish_dir: ./build
destination_dir: "docs/${{ env.PR_PATH }}"
cname: ${{ env.DOMAIN }}
# The following lines assign commit authorship to the official
# GH-Actions bot for deploys to `gh-pages` branch:
# https://github.com/actions/checkout/issues/13#issuecomment-724415212
# The GH actions bot is used by default if you didn't specify the two fields.
# You can swap them out with your own user credentials.
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com

- name: Update comment
uses: hasura/comment-progress@v2.2.0
if: github.ref != 'refs/heads/main'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
number: ${{ github.event.number }}
id: deploy-preview
message: "A preview of ${{ github.event.after }} is uploaded and can be seen here:\n\n ✨ ${{ env.BASE_URL }} ✨\n\nChanges may take a few minutes to propagate. The source is here: https://github.com/${{ github.repository }}/tree/gh-pages/${{ env.PR_PATH }}/"
31 changes: 31 additions & 0 deletions .github/workflows/pr-close.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: delete preview on PR close

# only trigger on pull request closed events
on:
pull_request:
types: [closed]

jobs:
delete_preview:
runs-on: ubuntu-20.04
env:
PR_PATH: pull/${{github.event.number}}
steps:
- name: make empty dir
run: mkdir public

- name: delete folder
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
destination_dir: ${{ env.PR_PATH }}

- name: Comment on PR
uses: hasura/comment-progress@v2.2.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
number: ${{ github.event.number }}
id: deploy-preview
message: "🪓 PR closed, deleted preview at https://github.com/${{ github.repository }}/tree/gh-pages/${{ env.PR_PATH }}/"
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# 🔎 Encrypted Variables - Preventing Exposure

Ensuring that encrypted data and variables are not leaked is important when working with Fhenix. A common oversight when working with encrypted variables is revealing them to other contracts. Lets take a look at a scenario that leaks encrypted data:

```solidity
contract UserBalanceVulnerable {
mapping(address => euint64) public eUserBalances;

function addBalance(inEuint64 calldata _inBalance) public {
eUserBalances[msg.sender] = eUserBalances[msg.sender].add(
FHE.asEuint64(_inBalance)
);
}
}
```

This seems secure enough and no decrypted data is directly exposed, however the `public` access to `eUserBalances` leaks sensitive data. A malicious contract is able to fetch this data and then decrypt it:

```solidity
contract UserBalanceAttack {
address private vulnerableContract;

function revealUserBalance(address _user) public view returns (uint64) {
return UserBalanceVulnerable(vulnerableContract)
.eUserBalances(_user)
.decrypt();
}
}
```

All contracts on the Fhenix network share an encryption key, therefore an encrypted variable in `ContractA` could be decrypted in `ContractB`.

This is not inherently wrong, and many operations will require encrypted variables to be shared between contracts, but care must be taken to prevent open access to encrypted variables.

### Hardhat Task

The `fhenix-hardhat-plugin` package contains a task that checks your contracts for any exposed encrypted variables. This task is run automatically when your contracts are compiled, but can also be run manually.

#### Task Example

The following contract exposes encrypted variables in 3 ways.

```solidity
pragma solidity >=0.8.13 <0.9.0;

import "@fhenixprotocol/contracts/FHE.sol";

contract ContractWithExposedVariables {
// Example 1
mapping(address => euint8) public eUserBalances;

// Example 2
mapping(address => euint8) private _eUserBalances;
function getUserBalance(address _user) public view returns (euint8) {
return _eUserBalances[_user];
}

// Example 3
struct Player {
address player;
euint8[] eCards;
uint256 chips;
uint256 bet;
}
struct Dealer {
uint256 pot;
euint8[] eFlopCards;
}
struct HoldEmGameState {
Player[] players;
Dealer dealer;
}

HoldEmGameState private gameState;
// Encrypted card values is the Player and Dealer structs are leaked and can be exploited
function getGameState() public view returns (HoldEmGameState memory) {
return gameState;
}
}
```

#### Output

Below is the output of the task when analyzing the above `ContractWithExposedVariables.sol`

<pre>
<b>fhenix-hardhat-plugin:CheckExposedEncryptedVars</b> checking for exposed encrypted variables....

<b style={{color:"orangered"}}>contracts/ContractWithExposedVariables.sol:ContractWithExposedVariables</b>

<b>eUserBalances(address)</b> exposes 1 encrypted variables:
pos-0 - <b style={{color:"orangered"}}>euint8</b>

<b>getUserBalance(address)</b> exposes 1 encrypted variables:
pos-0 - <b style={{color:"orangered"}}>euint8</b>

<b>getGameState()</b> exposes 1 encrypted variables:
pos-0 - struct ContractWithExposedVariables.HoldEmGameState
players - struct ContractWithExposedVariables.Player[]
eCards - <b style={{color:"orangered"}}>euint8[]</b>
dealer - struct ContractWithExposedVariables.Dealer
eFlopCards - <b style={{color:"orangered"}}>euint8[]</b>
</pre>

#### Manual Task Execution

The task can be run manually with the command:

```
npx hardhat task:fhenix:checkExposedEncryptedVars
```

Or as a part of a hardhat compilation:

```
npx hardhat compile
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# 📜 Permits & Access Control


In a Fully Homomorphic Encryption (FHE) framework, all data stored in a contract's storage is encrypted. Access control involves granting selective access to data by authorized parties while restricting access to unauthorized users.

Solidity contracts generally expose their data using `view` functions. However, permissioned data is a challenge, since Solidity `view` functions do not come with any in-built mechanism to allow the contract to verify cryptographically that callers are who they say they are (for transactions, this is done by verifying the signature on the data).
Fhenix handles this issue by implementing a `seal` function, which seals the data in a manner that only the intended recipient can decrypt and view (Fhenix uses the `decrypt` function for less sensitive data). This approach ensures that encrypted data remains confidential and only accessible to authorized users.

## Permits and Access Control

Fhenix Solidity libraries (specifically, fhenix.js) are equipped with an in-built access control scheme.
This access control scheme enables contracts to perform a basic check of account ownership by adding authentication and authorization features to specific view functions.
(An added benefit of the Fhenix Solidity libraries is that developers save coding effort each time a project has cryptographic access control requirements.)

#### What is a Permit?

A permit is a mechanism that allows the contract to verify cryptographically the identity of callers, ensuring that they are who they claim to be.

In Fhenix, a permit is a signed message that contains the caller's public key, which the contract can use to verify the caller. The permit is a signed JSON object that follows the EIP-712 standard.
The permit contains the necessary information, including a public key, which allows data re-sealing in a smart contract environment.
The inclusion of this public key into the permit enables a secure process of data re-sealing within a smart contract after the JSON object is signed by the user.

#### How to Generate a Permit

Permits are generated using the `generatePermit` method in `fhenix.js`. This method receives the following parameters:

* `contractAddress` (required, string): The address of the contract.
* `provider` (optional): An `ethers` (or compatible) object that can sign EIP-712 formatted data. (Note that if you want to unseal data using your wallet's encryption key you can't use "JsonRpcProvider")
* `signer` (optional): Another `ethers` (or compatible) signer if you want to use a different signer than the one in the provider (chain-id requests are still made via the provider)

```javascript
const permit = await generatePermit(contractAddress);

// passing a custom signer
let permit = await fhenixjs.generatePermit(
contractAddress,
undefined, // use the internal provider
signer, // created from, e.g. `ethers.getSigners()[0]`
);
```

#### What is a Permission?

In Fhenix, a permission is that part of a permit that supplies proof that callers are who they say they are.
A permission contains the signature and corresponding public key.
In order to see how to verify a permission in a Solidity contract, please refer to our [Permissioned](../Solidity%20API/Permissioned.md).

#### How to Generate a Permission

The following is the syntax for generating a permission:

```javascript
const permission = client.extractPermitPermissions(permit);
```

#### Using a Permission

Once generated, the permission can be used and sent to the contract. It can also be used to unseal the output of the `sealoutput` function, assuming it was sealed using that same permission.

The following code snippet shows how to implement the added cryptographic functionality of Fhenix (specifically, permits and permissions) on Ethereum using the Fhenix library.

```javascript
import { BrowserProvider } from "ethers";
import { FhenixClient, getPermit } from "fhenixjs";

const provider = new BrowserProvider(window.ethereum);
const client = new FhenixClient({ provider });
const permit = await generatePermit(contractAddress, provider);
const permission = client.extractPemitPermissions(permit);
const response = await contract.connect(owner).getValue(permission); // Calling "getValue" which is a view function in "contract"
const plaintext = await client.unseal(contractAddress, response);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 🤫 Development Tips – Ensuring Privacy

Fhenix provides a secure and decentralized way to execute smart contracts on encrypted data; transactions and computations are fully encrypted. As such, Fhenix offers superior on-chain privacy. However, developers still need to be vigilant, because all blockchain privacy platforms have their idiosyncrasies and potential privacy risks.

##### Implement Best Practices
Fhenix ensures end-to-end encryption, but developers should be careful not to become complacent on matters of privacy. Developers should always prioritize best practices to ensure privacy and confidentiality.

##### Analyze Your Privacy Model
We recommend that Fhenix developers carefully analyze their smart contract privacy model (this applies to any blockchain platform with privacy features). Distinguish between the type of information that, if “leaked,” can affect contract privacy on the one hand, and the type of information that, if compromised, will not affect contract operation and user privacy on the other. Special attention should be given to the type of information that must remain confidential.

As a result of this analysis and the insights gained, structure your smart contracts in a way that safeguards the aspects that affect privacy, while ensuring that the smart contract continues to operate efficiently.

##### A Simple Example
A simple example of metadata leakage is gas usage. Consider a smart contract coded in Solidity that contains a conditional statement. In this case, the path taken by the condition, though encrypted, may still reveal information. A typical scenario is a conditional branch based on the value of a private variable, where gas usage, events, or other metadata could reveal the branch taken.

```Javascript
function performActionBasedOnBalance(uint256 amount) public {
if (balance[msg.sender] >= amount) {
// perform some operation
} else {
// perform another operation
}
}
```

In the above Solidity example, someone observing the transaction could potentially infer the chosen branch based on gas usage, events or metadata, which would, in turn, indirectly reveal whether the sender's balance was greater than or equal to the specified amount.

This example might seem insignificant, but it is important to remember that transactions can often be cheaply simulated with different input parameters. In the above example, performing a logarithmic search would reveal the exact balance fairly quickly.

##### Add Access Controls
It is important to provide access controls to functions that handle sensitive data. For instance, a function revealing a user’s balance should only be accessible to that specific user. We discuss this issue further in the [section on access control](./Permits-Access-Control.md)

##### In Conclusion
Despite the embedded encryption protection provided by FHE, it is essential to understand and address potential risk areas that can compromise privacy. We will be updating this section and our other documentation as our product matures, so be sure to check back from time to time.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Encryption and Privacy",
"position": 11
}
Loading
Loading