Skip to content

feat: CRP-2823 add developer docs for IBE and timelocks #5811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 63 commits into from
Jun 12, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
bff46f9
add back draft from before
altkdf Jun 2, 2025
135dd35
Merge branch 'master' into alex/ibe
altkdf Jun 2, 2025
79f85ec
add back draft from before
altkdf Jun 2, 2025
e3e28ac
reset submodule
altkdf Jun 2, 2025
45bfdb7
draft for IBE
altkdf Jun 4, 2025
1484b30
...
altkdf Jun 4, 2025
ba41a82
...
altkdf Jun 4, 2025
9a6e98b
...
altkdf Jun 4, 2025
28b3116
...
altkdf Jun 4, 2025
eea0058
...
altkdf Jun 4, 2025
25f1deb
timelock
altkdf Jun 4, 2025
2132862
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
altkdf Jun 5, 2025
c6d955d
Apply suggestions from code review
altkdf Jun 6, 2025
4b87016
wip
altkdf Jun 6, 2025
8b5478b
revert changes to roadmap
altkdf Jun 6, 2025
40cdd5a
update code links
altkdf Jun 8, 2025
7947342
typo
altkdf Jun 8, 2025
c9b083a
auction~?~
altkdf Jun 8, 2025
784bdef
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
altkdf Jun 8, 2025
93edc12
Merge branch 'master' into alex/ibe
altkdf Jun 8, 2025
6241509
minor improvements
altkdf Jun 8, 2025
e0cca74
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
efab0d1
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
5a7268b
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
1de284e
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
d89375c
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
683e0a8
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
81987d4
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
638ac20
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 10, 2025
496d4fc
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
3d54e90
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
7be9d52
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
bc08677
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 10, 2025
35f75fb
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
76383ba
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
60c1df0
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
103d74f
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 10, 2025
fa9904e
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
fb1acae
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
dda4b5f
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
1faf4cc
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
65c71a8
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
44edf6d
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
dbb6e68
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
5c1b525
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
a966b97
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
3111c4d
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 10, 2025
860db67
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 11, 2025
5733937
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 11, 2025
bc668a0
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
308e5ab
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
f032d15
Update docs/building-apps/network-features/vetkeys/identity-based-enc…
andreacerulli Jun 11, 2025
c66d7fa
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
e3e3159
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
35321de
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
688cb6d
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
dce464e
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
a0531bf
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
915f2ad
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
b2b9992
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
2a59d84
Update docs/building-apps/network-features/vetkeys/timelock-encryptio…
andreacerulli Jun 11, 2025
4b3e07c
Merge branch 'master' into alex/ibe
andreacerulli Jun 12, 2025
adf8f08
Merge branch 'master' into alex/ibe
andreacerulli Jun 12, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---

keywords: [advanced, concept, vetkd, vetkeys, encryption, identity based encryption, threshold decryption, encrypted threshold key derivation]

---

import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow";
import TabItem from "@theme/TabItem";
import { AdornedTabs } from "/src/components/Tabs/AdornedTabs";

# Identity-based encryption (IBE)

<MarkdownChipRow labels={["Advanced", "vetKeys", "Identity-based encryption"]} />

Identity-Based Encryption (IBE) allows you to encrypt data directly to a user's identity, like an email address, a username, a principal ID, or a wallet address, without needing to exchange public keys beforehand or to rely on a public key infrastructure. This makes it possible to encrypt data for a specific user or account, even if that user has never previously interacted with the system. Once the user authenticates using their identity, they can securely retrieve their decryption key and access the data.

Compared to DKMS, IBE works differently. In DKMS, one or more users share the same symmetric key, and only those users can encrypt and decrypt data using that key. In contrast, IBE is an asymmetric encryption scheme. Anyone can encrypt messages to a given identity, including other users or canisters, but only the holder of the corresponding decryption key can decrypt them.

## How to use IBE?

In the following steps, to explain how to use IBE with vetKeys we show parts of the [basic IBE example](https://github.com/dfinity/vetkeys/tree/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_ibe), which implements a simple IBE messaging system between principals.

### Step 1: Obtain the IBE public key

Expose a canister endpoint that allows to fetch the IBE public key of the canister.

<AdornedTabs groupId="languages">

<TabItem value="rs" label="Rust" default>

```rust no-repl reference
https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_ibe/backend/src/lib.rs#L57-L74
```

</TabItem>
</AdornedTabs>

To obtain the public key in the frontend, you now only need to make a call to this endpoint, e.g., like it is done [here](https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_ibe/frontend/src/main.ts#L57).
The public key needs to only be fetched once and it can be used to encrypt data for multiple recipients by deriving corresponding subkeys locally.

### Step 2: Encrypt data
Use the [frontend `@dfinity/vetkeys` library](https://dfinity.github.io/vetkeys/classes/_dfinity_vetkeys.IbeCiphertext.html#encrypt) to encrypt data and store it in the canister.

<AdornedTabs groupId="languages">

<TabItem value="ts" label="TypeScript" default>

```ts no-repl reference
https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_ibe/frontend/src/main.ts#L85-L119
```

</TabItem>
</AdornedTabs>

### Step 3: Obtain the IBE private key

Expose a canister endpoint that allows to fetch the IBE private key of the user making the call.

<AdornedTabs groupId="languages">

<TabItem value="rs" label="Rust" default>

```rust no-repl reference
https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_ibe/backend/src/lib.rs#L76-L96
```

</TabItem>
</AdornedTabs>

To obtain the private key in the frontend, you now only need to make a call to this endpoint, e.g., like it is done [here](https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_ibe/frontend/src/main.ts#L71).
The transport public key required for the call is a throw-away key that is generated by the [`@dfinity/vetkeys` library](https://dfinity.github.io/vetkeys/classes/_dfinity_vetkeys.TransportSecretKey.html#random) in the frontend.
The public key needs to only be fetched once and it can be used to encrypt data for multiple recipients by deriving corresponding subkeys locally.

### Step 4: Decrypt data
Obtain the encrypted data from the canister or other storage location.
Decrypt the IBE-encrypted data in the frontend using the [frontend `@dfinity/vetkeys` library](https://dfinity.github.io/vetkeys/classes/_dfinity_vetkeys.IbeCiphertext.html#decrypt).
See more details on the [API page](/docs/building-apps/network-features/vetkeys/api) for more details regarding the basic flow of obtaining vetKeys.

<AdornedTabs groupId="languages">

<TabItem value="ts" label="TypeScript" default>

```ts no-repl reference
https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_ibe/frontend/src/main.ts#L126-L132
```

</TabItem>
</AdornedTabs>

## Demos

- [Use IBE to encrypt and send files to Ethereum wallets using a React frontend and Rust backend](https://github.com/kristoferlund/send_file_to_eth_demo).
10 changes: 3 additions & 7 deletions docs/building-apps/network-features/vetkeys/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,17 @@ A core application of DKMS is the generation of encryption keys for securing dat

The corresponding documentation will be added soon.

## Identity-based encryption (IBE)
## [Identity-based encryption (IBE)](/docs/building-apps/network-features/vetkeys/identity-based-encryption)

vetKeys enables IBE, allowing data to be encrypted directly to an identity, such as a principal, an Internet Identity, an email address, or even an Ethereum address. This makes it possible to encrypt data for a specific user or account, even if that user has never previously interacted with the dapp. By authenticating with the dapp using their identity, the user can securely retrieve their decryption key and access the data.
The vetKeys feature enables IBE, allowing data to be encrypted directly to an identity, such as a principal, an Internet Identity, an email address, or even an Ethereum address. This makes it possible to encrypt data for a specific user or account, even if that user has never previously interacted with the dapp. By authenticating with the dapp using their identity, the user can securely retrieve their decryption key and access the data.

Compared to DKMS, IBE works differently. In DKMS, one or more users share **the same** symmetric key, and only those users can encrypt and decrypt data using that key. In contrast, IBE is an **asymmetric encryption** scheme. Anyone can encrypt messages to a given identity, including other users or canisters, but only the holder of the corresponding decryption key can decrypt them.

The corresponding documentation will be added soon.

## Timelock encryption
## [Timelock encryption](/docs/building-apps/network-features/vetkeys/timelock-encryption)

A special variant of IBE is called timelock encryption. It allows a sender to encrypt to a specific timestamp, ensuring that the recipient can only decrypt after the specific time has passed. Canisters can enforce this time-based access control by requesting threshold decryption of a ciphertext only after a predetermined expiry time, keeping sensitive information secret until the appropriate moment. This makes it possible to implement time-sensitive applications, like secret-bid auctions, time-locked documents, dead-man switches, and delayed reveal NFTs.
Timelock encryption also serves as a key building block for protecting against maximal extractable value (MEV). By keeping transaction details confidential until after block inclusion, it prevents adversaries from doing front-running and reordering of transactions.

The corresponding documentation will be added soon.

## Externally verifiable randomness

vetKeys can also function as a Verifiable Random Function (VRF). This means that canisters can generate randomness that is not only unpredictable and tamperproof but also publicly verifiable. Trusted randomness is a critical building block for a wide range of decentralized applications, including trustless online lotteries, fair casino games, and GameFi experiences where outcomes must be demonstrably fair. It also plays a key role in NFT ecosystems, for example, in assigning randomized traits or rarities during minting, or enabling dynamic, chance-based in-game interactions.
Expand Down
101 changes: 101 additions & 0 deletions docs/building-apps/network-features/vetkeys/timelock-encryption.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
keywords: [advanced, concept, random, randomness, onchain randomness, raw_rand]
---

import { MarkdownChipRow } from "/src/components/Chip/MarkdownChipRow";
import TabItem from "@theme/TabItem";
import useBaseUrl from "@docusaurus/useBaseUrl";
import { AdornedTabs } from "/src/components/Tabs/AdornedTabs";
import { AdornedTab } from "/src/components/Tabs/AdornedTab";
import { BetaChip } from "/src/components/Chip/BetaChip";

# Timelock encryption

<MarkdownChipRow labels={["Advanced", "vetKeys", "Identity-based encryption", "Timelock"]} />

A special variant of [identity-based encryption (IBE)](/docs/building-apps/network-features/vetkeys/identity-based-encryption) is called timelock encryption.
It allows a sender to encrypt to a specific timestamp, ensuring that the recipient can only decrypt after the specific time has passed. Canisters can enforce this time-based access control by requesting threshold decryption of a ciphertext only after a predetermined expiry time, keeping sensitive information secret until the appropriate moment.
This makes it possible to implement time-sensitive applications, like secret-bid auctions, time-locked documents, dead-man switches, and delayed reveal NFTs.
Timelock encryption also serves as a key building block for protecting against maximal extractable value (MEV). By keeping transaction details confidential until after block inclusion, it prevents adversaries from doing front-running and reordering of transactions.

## Use cases

### Birthday coupon

A user can encrypt a coupon or gift, send it to another user, who can only decrypt it after a certain delay such as the time until their birthday.

### Secret-bid auctions and MEV protection

In a secret-bid auction dapp, users can submit bids that are IBE-encrypted under an identifier so that at the end of the auction, the dapp can decrypt all bids with a single vetKey evaluation. A similar technique can be used to prevent front-running, also known as maximal extractable value (MEV), on a decentralized exchange (DEX). Users submit their IBE-encrypted transactions under a predictable batch identifier. The DEX orders the transactions in encrypted form and, when all transactions for a particular batch have been ordered, triggers the recovery of the decryption key for that batch and executes the decrypted transactions in the fixed order. Note that all of the symmetric-encryption use cases listed above can be modified to encrypt using an IBE instead of a symmetric-key encryption, thereby eliminating the need to perform a vetKey derivation for encryption. Decryption, of course, still requires retrieving a vetKey.

### "Dead man's switch"

Journalists or whistleblowers could ensure that compromising information in their possession is automatically published if they were to become incapacitated. They can store the information in a dapp, encrypted using IBE that the dapp automatically and publicly recovers when a certain amount of time passes after it last received an authenticated ping from its owner.

### Advanced timelocks

Anyone can IBE-encrypt their message using a more complex condition as the identity, while a dapp allows anyone who can satisfy that condition, or when the condition is automatically fulfilled, to obtain the corresponding vetKey. This enables interesting use cases by allowing encryption tied to verifiable future events. For example, one could encrypt a message that becomes decryptable only when the price of a stock rises above or falls below a certain level, or implement information escrow and break-the-glass policies.

## How to use timelock encryption?

We can categorize timelock encryption into two categories: 1. scenario where the canister decrypts, and 2. scenario where the user decrypts.
The latter is essentially the same as the [IBE](/docs/building-apps/network-features/vetkeys/identity-based-encryption), only with additional conditions on when the key can be obtained by the authorized users.
This can be as simple as checking if enough time has passed and either returning the key or an error to the user.
Therefore, let's focus on getting the first case to work.

The code in the descriptions below is taken from the [secret-bid auction example](https://github.com/dfinity/vetkeys/tree/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_timelock_ibe), where any user can create an auction lot with a deadline and other users can create IBE-encrypted bids for the open lots.
The encrypted bids are decrypted by the canister once the deadline has passed and the lot was closed.
From that moment on, the bids become public and the canister announces the winner of the lot.

### Step 1: Obtain IBE public key

Expose a canister endpoint that allows to fetch the IBE public key of the canister.

<AdornedTabs groupId="languages">

<TabItem value="rs" label="Rust" default>

```rust no-repl reference
https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_timelock_ibe/backend/src/lib.rs#L88-L109
```

</TabItem>
</AdornedTabs>

To obtain the public key in the frontend, you now only need to make a call to this endpoint, e.g., like it is done [here](https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_timelock_ibe/frontend/src/main.ts#L53).
The public key needs to only be fetched once and it can be used to encrypt data for multiple recipients by deriving corresponding subkeys locally.

### Step 2: Encrypt data in the frontend

Use the [frontend `@dfinity/vetkeys` library](https://dfinity.github.io/vetkeys/classes/_dfinity_vetkeys.IbeCiphertext.html#encrypt) to encrypt data and store it in the canister.
The `lotId` variable is the identity that we encrypt to to place a bid with the `amount` specified by the user.

<AdornedTabs groupId="languages">

<TabItem value="ts" label="TypeScript" default>

```ts no-repl reference
https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_timelock_ibe/frontend/src/main.ts#L406-L429
```

</TabItem>
</AdornedTabs>

### Step 3: Decrypt data in the backend once conditions are met

The condition for decryption in the secret bid auction example is that the current time should be after the deadline time.
In the example, it is checked by simply comparing the stored timestamp with the timestamp of the current time (see [code here](https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_timelock_ibe/backend/src/lib.rs#L217)).
There, a timer is invoked periodically to check if there are any lots to close which triggers the lot closure and bid decryption.
The latter is implemented in the `decrypt_bids` function showed below.

<AdornedTabs groupId="languages">

<TabItem value="rs" label="Rust" default>

```rust no-repl reference
https://github.com/dfinity/vetkeys/blob/3b1de5d546dcc32daaf22b21baaa2b220bc857f3/examples/basic_timelock_ibe/backend/src/lib.rs#L284-L352
```

</TabItem>
</AdornedTabs>

2 changes: 2 additions & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ build: [
"building-apps/network-features/vetkeys/api",
"building-apps/network-features/vetkeys/dkms",
"building-apps/network-features/vetkeys/encrypted-onchain-storage",
"building-apps/network-features/vetkeys/identity-based-encryption",
"building-apps/network-features/vetkeys/timelock-encryption",
],
},
"building-apps/network-features/randomness",
Expand Down