Skip to main content

Overview

zkStorage provides encrypted file storage on IPFS with zero-knowledge proofs for password verification. Files are encrypted client-side before upload, ensuring only you can access your data.

How It Works

  1. Encrypt: Files are encrypted client-side using AES-256-GCM with a key derived from your password.
  2. Generate Proof: A Groth16 zkSNARK proof is generated proving you know the password without revealing it.
  3. Upload: Encrypted file is uploaded to IPFS via Pinata with the proof attached.
  4. Verify: Download requires verifying the ZK proof to decrypt the file.

Terminal Commands

Show Help

zk storage help
Shows all available zkStorage commands and security details.

Upload File

zk storage upload
Opens a file picker for encrypted upload. After selecting a file, you’ll be prompted for a password. Example:
> zk storage upload
[File picker opens]
Password: ********
Encrypting file (1.2 MB)...
Generating ZK proof...
Uploading to IPFS...

Success!
CID: QmXyz123abc456def789

List Files

zk storage list
Shows all your uploaded files with CID, name, size, and date.
> zk storage list

Your zkStorage Files:

[1] document.pdf [ZK]
    CID: QmXyz123...
    Size: 1.2 MB
    Uploaded: Dec 1, 2025

[2] image.png [ZK]
    CID: QmAbc456...
    Size: 500 KB
    Uploaded: Nov 30, 2025

Download File

zk storage download <file-id>
Downloads and decrypts a file. Requires password for decryption. Example:
> zk storage download QmXyz123
Password: ********
Verifying ZK proof...
Downloading from IPFS...
Decrypting file...
Saved to: document.pdf

Share File

zk storage share <file-id>
Creates a shareable link with time-limited access.

File Info

zk storage info <file-id>
Shows detailed information about a specific file.

Delete File

zk storage delete <file-id>
Unpins a file from IPFS (removes from Pinata).

API Reference

Upload File

POST /api/storage/upload
Content-Type: multipart/form-data

file: <binary>
encryptedData: <encrypted-base64>
iv: <iv-base64>
salt: <salt-base64>
commitment: <poseidon-hash>
proof: <groth16-proof-json>
publicSignals: <proof-signals>
Response:
{
  "success": true,
  "cid": "QmXyz123...",
  "fileId": "uuid",
  "originalName": "document.pdf",
  "originalSize": 1234567,
  "zkEnabled": true
}

List Files

GET /api/storage/files
Response:
{
  "files": [
    {
      "id": "uuid",
      "cid": "QmXyz123...",
      "originalName": "document.pdf",
      "originalSize": 1234567,
      "zkEnabled": true,
      "createdAt": "2025-12-01T10:00:00Z"
    }
  ]
}

Download File

POST /api/storage/download
Content-Type: application/json

{
  "fileId": "uuid",
  "proof": {...},
  "publicSignals": [...]
}
Response: Binary encrypted file data
POST /api/storage/share
Content-Type: application/json

{
  "fileId": "uuid",
  "expiresIn": 86400
}
Response:
{
  "shareUrl": "https://zkterm.io/share/abc123",
  "expiresAt": "2025-12-02T10:00:00Z"
}

Delete File

DELETE /api/storage/files/<fileId>
Response:
{
  "success": true,
  "message": "File deleted"
}

Technical Details

Encryption

zkStorage uses AES-256-GCM for file encryption:
const key = await crypto.subtle.deriveKey(
  { name: "PBKDF2", salt, iterations: 100000, hash: "SHA-256" },
  passwordKey,
  { name: "AES-GCM", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

const encrypted = await crypto.subtle.encrypt(
  { name: "AES-GCM", iv },
  key,
  fileData
);

ZK Proof Generation

Groth16 proofs verify password knowledge using Poseidon hash commitments:
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
  { password: passwordHash },
  "circuits/password.wasm",
  "circuits/password_final.zkey"
);

IPFS Storage

Files are stored on IPFS via Pinata:
  1. Gateway: gateway.pinata.cloud
  2. Persistence: Files remain pinned indefinitely
  3. Redundancy: Multiple IPFS nodes

File Limits

LimitValue
Max file size100 MB
EncryptionAES-256-GCM
StorageIPFS via Pinata

Security Features

  1. Client-Side Encryption: Files encrypted before leaving your device.
  2. Zero-Knowledge Proofs: Password verified without revealing it.
  3. AES-256-GCM: Military-grade authenticated encryption.
  4. SHA-256 Checksums: Verify file integrity on download.
  5. Time-Limited Sharing: Share links expire automatically.
Important: If you forget your password, your files cannot be recovered. There is no password reset.

Error Handling

ErrorCauseSolution
Invalid proofWrong passwordEnter correct password
CID not foundFile unpinnedFile no longer available
Checksum mismatchFile corruptedRe-upload the file
Proof generation failedCircuit errorCheck password format

Example: Full Flow

# 1. Upload a file
> zk storage upload
[File picker opens - select secret_document.pdf]
Password: ********
Confirm password: ********
Encrypting file (1.2 MB)...
Generating Groth16 proof...
Uploading to IPFS...

Success!
CID: QmXyz123abc456def789

# 2. List your files
> zk storage list

Your zkStorage Files:

[1] secret_document.pdf [ZK]
    CID: QmXyz123...
    Size: 1.2 MB
    Uploaded: Dec 1, 2025

# 3. Download later
> zk storage download QmXyz123
Password: ********
Verifying proof...
Downloading from IPFS...
Decrypting...
Verifying checksum...
Saved to: secret_document.pdf