
Fangorn is programmable secrets infrastructure; the if statement for web3. It enables a trustless, extensible logic layer for encrypted data, where access is granted based on proof, not permission. There is no corporation-in-the-middle imposing policies, no server storing the password, and nobody who can usurp your own agency.
This article walks you through our first demo: proof-of-knowledge-protected vaults built with LIT protocol (for secure decentralized key management), Noir (for zero-knowledge logic), and deployed on Base. Fangorn extends LIT by adding verifiable, programmable conditions whose proofs are verified trustlessly on-chain rather than relying solely on a TEE (trusted execution environment). For simple use cases, LIT works, but for complex, trust-minimized, or privacy-preserving conditions, Fangorn + LIT is the right combination.
Fangorn implements a practical, trust-minimized approximation of witness encryption. To better understand what Fangorn does, it helps to look at an example from cryptographic literature.
Imagine a Sudoku puzzle published publicly. With Fangorn, secrets can be encrypted such that anyone who can solve the puzzle can decrypt the message. The puzzle author doesn't share the solution and doesn't need to know who the players are. Decryption does not require a secret key, key exchange, any prior knowledge, or interaction between parties at all. There is no man-in-the-middle or centralized authority who needs to coordinate the process.
Fangorn generalizes this idea: in this initial demo the witness is simple knowledge (e.g. a password), with more expressive and composable conditions on the way - puzzles, proofs, payments, agent-bound intent, and more.
The demo presents a deliberately simple use case for Fangorn: content that unlocks only by proving you know a specific piece of information. This could be anything, like a password (as in the vault demo), the solution to a puzzle like a Sudoku, or even GPS coordinates. Users can create their own protected vaults, add data, and share the ciphertext. Data access is granted by proving you know the vault secret and can prove membership of the requested content in the vault, without revealing either.
Try it out at https://vault-demo.fangorn.network/
Login!
First grab some testnet tokens from the Coinbase faucet.
Then, navigate to https://vault-demo.fangorn.network and authorize the sign-in request.

Create a vault
Each vault is secured by a secret. Only someone who can prove they know the secret can decrypt the contents. Click through to sign the transaction (omitted from gif).

Add Files
Vaults can contain many items, with support for any file type. Each blob is encrypted and pinned to IPFS. Click through to sign the transaction (omitted from gif).

Share the Vault link
Each blob uploaded to a vault can be shared with a unique link, allowing for proof-of-knowledge-protected data to be easily shared between parties.

Recipient proves they know the password
Users prepare a zero-knowledge proof and submit it for trustless verification on-chain. The ZkGate contract tracks both nullifiers (preventing double spending of proofs) and verification (you don't need to reverify for future attempts). Click through to sign the transaction (omitted from gif).

Decryption happens client-side if and only if a proof has been verified, meaning:
the plaintext password never leaves your device
no server ever sees the password or knows which content you're accessing
proof verification is trustless and low-cost (<$0.01).
Proofs are generated in the browser for now, which could be slow for larger proofs in the future. Our roadmap includes optimizations, like WebGPU acceleration, to reduce execution times.
The current storage implementation is naive. The demo application pins all files to a single Pinata gateway managed by the Fangorn team. In addition, the fangorn-sdk requires that you use Pinata, which is far more opinionated than we desire. Fangorn is intended to be a bring-your-own-storage solution, but we left storage as-is for now in order to simplify UX.
There are four major components that make this all work:
Noir for trustless verification of zero-knowledge proofs
Access control is gated by valid proofs for the circuit (password + Merkle membership). By verifying this proof on-chain, access can be granted without leaking the data being accessed.
IPFS (Pinata) for immutable, off-chain decentralized storage
Fangorn is a bring-your-own-storage solution, though we encourage immutable decentralized storage. The current dapp demonstration uses Pinata for simplicity.
LIT's network for trust minimized threshold encryption
Decryption keys are released only when a well-defined lit-action is executed successfully by at least a threshold of node operators.
How Fangorn and LIT work together
LIT provides the threshold encryption primitive, while Fangorn provides the composable ZK condition framework on top of it. LIT handles the "how" and Fangorn handles "when" decryption keys are released through expressive, verifiable on-chain proofs. With Fangorn, encryption conditions can be composed, extended, and adapted to new use cases without changing the underlying encryption layer, while all proof verification is performed and stored trustlessly on-chain.
A ZkGate contract deployed on Base Sepolia
The ZkGate contract tracks verified proofs on chain. It is deployed on Base Sepolia, a low cost, low-trust execution environment that we rely on for proof verification, It requires $<0.01 per verification. The solution does not require Base nor are we affiliated with it in any way. Our roadmap includes support for various zkEVM chains.

A vault represents a collection of password-gated user-owned content. Each vault tracks its content through a manifest. A manifest is a Merkle tree stored in IPFS; its leaves are encrypted content and the root is tightly coupled to the vault on-chain.
A vault is an entry in the ZKGate contract that stores:
passwordHash - SHA256 hash of the vault password
poseidonRoot - Root of the manifest's Merkle tree
manifestCid - CID pointing to the full manifest on IPFS
owner - Wallet address of the vault owner
Vault IDs are derived internally: SHA256(callerAddress || passwordHash)
Each leaf is a VaultEntry:
tag - Unique name for the content
cid - CID of the ciphertext on IPFS
index - Position in the manifest
leaf - Commitment: Poseidon2(vaultId, tag)
This structure provides two core benefits:
Efficient and Immutable State: The on-chain state only stores the Merkle root represented with 32 bytes. Adding or removing content updates the root but does not increase on-chain storage requirements.
Confidential Access Requests: When requesting decryption, you only prove the content exists within the vault and that you know the password, without revealing which content it is or what the password is. Observers may see that something was accessed from a given vault, but not what was accessed.
The circuit is written with Noir and verified on Base using the Barretenberg verifier.
For any given vault, valid proofs must demonstrate:
you know the password
you know the CID of the ciphertext
that the CID is a valid leaf in the vault's Merkle tree
without leaking the CID or the password.
The ZkGate contract is minimal. It acts as a proxy to the verifier contract and as a store of valid proofs, ensuring that:
proofs cannot be double spent
proofs do not need to be re-verified - access is granted in perpetuity.
The account who has access, the vault id accessed, and a hash of the CID are stored on-chain, but future iterations will add enhanced privacy.
LIT protocol handles threshold encryption. LIT actions are executables that are run by LIT network operators that allow decryption (and signing) to be gated behind immutable logic within a TEE (trusted execution environment).
The LIT action used by Fangorn is very basic - simply querying the ZkGate contract to check for access. Currently, the VaultId and the user address are revealed to the LIT action, but future versions will add enhanced privacy. If a caller has verified a proof for some specific content in a specific vault, Lit releases a decryption key, otherwise nothing happens.
Visit the github for a more in-depth dev guide: https://github.com/fangorn-network/fangorn
Explore the app: https://github.com/fangorn-network/app
Install the SDK with:
npm i fangorn-sdkFangorn is a bring-your-own-storage solution. The current SDK is opinionated and requires that you use the Pinata SDK. In order to use the fangorn-sdk, first create an account at https://pinata.cloud/ and generate a JWT by following the instructions.
// your domain w/o `https://www.`
const domain = "your.domain";
const fangorn = await Fangorn.init(account, jwt, gateway, domain);
const vaultId = await fangorn.createVault("my-vault", "secretpassword");
await fangorn.upload(vaultId, [
{ tag: "document-1", data: "my-data", extension: ".txt", fileType: "text/json" },
]);const fangorn = await Fangorn.init(account, jwt, gateway);
const plaintext = await fangorn.decryptFile(vaultId, "document-1", "secretpassword");Password protection is just the first gadget. The Fangorn-SDK aims to be "the if statement for web3": a modular and extensible zk-gadget framework, enabling many, basic 'gadgets' to be composed to form more complex, expressive circuits (using recursive proofs) for intent-bound data (data that unlocks only when conditions are met) and intent-bound signing (digital signatures issued when conditions are met). We are building tools that enable access based on proof, not permission, without leaking intent or relying on brittle, opaque policies.
We started with passwords, but next will be identity, allow lists, token ownership, and x402 payments, laying down the building blocks for a fully decentralized, trustless data platforms for the next stage of the web.
For the full vision:
read our vision document at https://paragraph.com/@fangorn/fangorn
and visit our website https://fangorn.network
If you're already building LIT actions and need more expressive or privacy preserving conditions, reach out and build with us!
Live demo: https://vault-demo.fangorn.network
Website https://fangorn.network
Join our discord! https://discord.gg/JDj8RdCVyU

Fangorn is programmable secrets infrastructure; the if statement for web3. It enables a trustless, extensible logic layer for encrypted data, where access is granted based on proof, not permission. There is no corporation-in-the-middle imposing policies, no server storing the password, and nobody who can usurp your own agency.
This article walks you through our first demo: proof-of-knowledge-protected vaults built with LIT protocol (for secure decentralized key management), Noir (for zero-knowledge logic), and deployed on Base. Fangorn extends LIT by adding verifiable, programmable conditions whose proofs are verified trustlessly on-chain rather than relying solely on a TEE (trusted execution environment). For simple use cases, LIT works, but for complex, trust-minimized, or privacy-preserving conditions, Fangorn + LIT is the right combination.
Fangorn implements a practical, trust-minimized approximation of witness encryption. To better understand what Fangorn does, it helps to look at an example from cryptographic literature.
Imagine a Sudoku puzzle published publicly. With Fangorn, secrets can be encrypted such that anyone who can solve the puzzle can decrypt the message. The puzzle author doesn't share the solution and doesn't need to know who the players are. Decryption does not require a secret key, key exchange, any prior knowledge, or interaction between parties at all. There is no man-in-the-middle or centralized authority who needs to coordinate the process.
Fangorn generalizes this idea: in this initial demo the witness is simple knowledge (e.g. a password), with more expressive and composable conditions on the way - puzzles, proofs, payments, agent-bound intent, and more.
The demo presents a deliberately simple use case for Fangorn: content that unlocks only by proving you know a specific piece of information. This could be anything, like a password (as in the vault demo), the solution to a puzzle like a Sudoku, or even GPS coordinates. Users can create their own protected vaults, add data, and share the ciphertext. Data access is granted by proving you know the vault secret and can prove membership of the requested content in the vault, without revealing either.
Try it out at https://vault-demo.fangorn.network/
Login!
First grab some testnet tokens from the Coinbase faucet.
Then, navigate to https://vault-demo.fangorn.network and authorize the sign-in request.

Create a vault
Each vault is secured by a secret. Only someone who can prove they know the secret can decrypt the contents. Click through to sign the transaction (omitted from gif).

Add Files
Vaults can contain many items, with support for any file type. Each blob is encrypted and pinned to IPFS. Click through to sign the transaction (omitted from gif).

Share the Vault link
Each blob uploaded to a vault can be shared with a unique link, allowing for proof-of-knowledge-protected data to be easily shared between parties.

Recipient proves they know the password
Users prepare a zero-knowledge proof and submit it for trustless verification on-chain. The ZkGate contract tracks both nullifiers (preventing double spending of proofs) and verification (you don't need to reverify for future attempts). Click through to sign the transaction (omitted from gif).

Decryption happens client-side if and only if a proof has been verified, meaning:
the plaintext password never leaves your device
no server ever sees the password or knows which content you're accessing
proof verification is trustless and low-cost (<$0.01).
Proofs are generated in the browser for now, which could be slow for larger proofs in the future. Our roadmap includes optimizations, like WebGPU acceleration, to reduce execution times.
The current storage implementation is naive. The demo application pins all files to a single Pinata gateway managed by the Fangorn team. In addition, the fangorn-sdk requires that you use Pinata, which is far more opinionated than we desire. Fangorn is intended to be a bring-your-own-storage solution, but we left storage as-is for now in order to simplify UX.
There are four major components that make this all work:
Noir for trustless verification of zero-knowledge proofs
Access control is gated by valid proofs for the circuit (password + Merkle membership). By verifying this proof on-chain, access can be granted without leaking the data being accessed.
IPFS (Pinata) for immutable, off-chain decentralized storage
Fangorn is a bring-your-own-storage solution, though we encourage immutable decentralized storage. The current dapp demonstration uses Pinata for simplicity.
LIT's network for trust minimized threshold encryption
Decryption keys are released only when a well-defined lit-action is executed successfully by at least a threshold of node operators.
How Fangorn and LIT work together
LIT provides the threshold encryption primitive, while Fangorn provides the composable ZK condition framework on top of it. LIT handles the "how" and Fangorn handles "when" decryption keys are released through expressive, verifiable on-chain proofs. With Fangorn, encryption conditions can be composed, extended, and adapted to new use cases without changing the underlying encryption layer, while all proof verification is performed and stored trustlessly on-chain.
A ZkGate contract deployed on Base Sepolia
The ZkGate contract tracks verified proofs on chain. It is deployed on Base Sepolia, a low cost, low-trust execution environment that we rely on for proof verification, It requires $<0.01 per verification. The solution does not require Base nor are we affiliated with it in any way. Our roadmap includes support for various zkEVM chains.

A vault represents a collection of password-gated user-owned content. Each vault tracks its content through a manifest. A manifest is a Merkle tree stored in IPFS; its leaves are encrypted content and the root is tightly coupled to the vault on-chain.
A vault is an entry in the ZKGate contract that stores:
passwordHash - SHA256 hash of the vault password
poseidonRoot - Root of the manifest's Merkle tree
manifestCid - CID pointing to the full manifest on IPFS
owner - Wallet address of the vault owner
Vault IDs are derived internally: SHA256(callerAddress || passwordHash)
Each leaf is a VaultEntry:
tag - Unique name for the content
cid - CID of the ciphertext on IPFS
index - Position in the manifest
leaf - Commitment: Poseidon2(vaultId, tag)
This structure provides two core benefits:
Efficient and Immutable State: The on-chain state only stores the Merkle root represented with 32 bytes. Adding or removing content updates the root but does not increase on-chain storage requirements.
Confidential Access Requests: When requesting decryption, you only prove the content exists within the vault and that you know the password, without revealing which content it is or what the password is. Observers may see that something was accessed from a given vault, but not what was accessed.
The circuit is written with Noir and verified on Base using the Barretenberg verifier.
For any given vault, valid proofs must demonstrate:
you know the password
you know the CID of the ciphertext
that the CID is a valid leaf in the vault's Merkle tree
without leaking the CID or the password.
The ZkGate contract is minimal. It acts as a proxy to the verifier contract and as a store of valid proofs, ensuring that:
proofs cannot be double spent
proofs do not need to be re-verified - access is granted in perpetuity.
The account who has access, the vault id accessed, and a hash of the CID are stored on-chain, but future iterations will add enhanced privacy.
LIT protocol handles threshold encryption. LIT actions are executables that are run by LIT network operators that allow decryption (and signing) to be gated behind immutable logic within a TEE (trusted execution environment).
The LIT action used by Fangorn is very basic - simply querying the ZkGate contract to check for access. Currently, the VaultId and the user address are revealed to the LIT action, but future versions will add enhanced privacy. If a caller has verified a proof for some specific content in a specific vault, Lit releases a decryption key, otherwise nothing happens.
Visit the github for a more in-depth dev guide: https://github.com/fangorn-network/fangorn
Explore the app: https://github.com/fangorn-network/app
Install the SDK with:
npm i fangorn-sdkFangorn is a bring-your-own-storage solution. The current SDK is opinionated and requires that you use the Pinata SDK. In order to use the fangorn-sdk, first create an account at https://pinata.cloud/ and generate a JWT by following the instructions.
// your domain w/o `https://www.`
const domain = "your.domain";
const fangorn = await Fangorn.init(account, jwt, gateway, domain);
const vaultId = await fangorn.createVault("my-vault", "secretpassword");
await fangorn.upload(vaultId, [
{ tag: "document-1", data: "my-data", extension: ".txt", fileType: "text/json" },
]);const fangorn = await Fangorn.init(account, jwt, gateway);
const plaintext = await fangorn.decryptFile(vaultId, "document-1", "secretpassword");Password protection is just the first gadget. The Fangorn-SDK aims to be "the if statement for web3": a modular and extensible zk-gadget framework, enabling many, basic 'gadgets' to be composed to form more complex, expressive circuits (using recursive proofs) for intent-bound data (data that unlocks only when conditions are met) and intent-bound signing (digital signatures issued when conditions are met). We are building tools that enable access based on proof, not permission, without leaking intent or relying on brittle, opaque policies.
We started with passwords, but next will be identity, allow lists, token ownership, and x402 payments, laying down the building blocks for a fully decentralized, trustless data platforms for the next stage of the web.
For the full vision:
read our vision document at https://paragraph.com/@fangorn/fangorn
and visit our website https://fangorn.network
If you're already building LIT actions and need more expressive or privacy preserving conditions, reach out and build with us!
Live demo: https://vault-demo.fangorn.network
Website https://fangorn.network
Join our discord! https://discord.gg/JDj8RdCVyU
<100 subscribers
<100 subscribers
Share Dialog
Share Dialog
No comments yet