Skip to main content

Choosing the Right Package

Find the perfect ZK-Kit package for your use case.

Decision Tree

Start Here

├─ Need Merkle Trees?
│ ├─ YES → Which type?
│ │ ├─ Membership proofs only → IMT
│ │ ├─ Low memory required → LeanIMT
│ │ └─ Key-value + non-membership → SMT
│ │
│ └─ NO → Need cryptography?
│ ├─ Digital signatures → EdDSA-Poseidon
│ ├─ Encryption → Poseidon Cipher
│ ├─ ZK proofs → Poseidon Proof
│ └─ Low-level curves → Baby JubJub

└─ Need utilities?
├─ Field operations → Utils
└─ Boolean logic → Logical Expressions

Merkle Tree Selection

IMT vs LeanIMT vs SMT

FeatureIMTLeanIMTSMT
Memory UsageHighLowMedium
SpeedFastMediumMedium
Max SizeFixed (2^depth)Dynamic2^256
Non-membership Proofs
Key-Value Storage
Updates
Deletes⚠️ (sets to zero)⚠️ (sets to zero)
Best ForMost appsMemory-limitedKey-value + proofs

When to Use IMT

Use IMT when:

  • Building standard membership proofs
  • Memory not constrained
  • Need fast operations
  • Size is predictable
npm i @zk-kit/imt

See npm page for peer dependencies

Example use cases:

  • Voting systems
  • Access control
  • Whitelist verification
  • Anonymous credentials

→ IMT on npm | GitHub

When to Use LeanIMT

Use LeanIMT when:

  • Memory is limited
  • Running on constrained devices
  • Size unknown upfront
  • Can trade speed for memory
npm i @zk-kit/lean-imt

See npm page for peer dependencies

Example use cases:

  • Mobile applications
  • Edge computing
  • Embedded systems
  • Serverless functions

→ LeanIMT on npm | GitHub

When to Use SMT

Use SMT when:

  • Need key-value storage
  • Need to prove key absence
  • Frequent updates/deletes
  • Keys are not sequential
npm i @zk-kit/smt crypto-js

Example use cases:

  • Account balances
  • State management
  • Non-membership proofs
  • Database with ZK

→ SMT on npm | GitHub

Cryptography Selection

EdDSA-Poseidon

Use for: Digital signatures in zero-knowledge circuits

npm i @zk-kit/eddsa-poseidon

Choose EdDSA-Poseidon when:

  • Need to sign messages
  • Verify signatures in circuits
  • Build authentication systems
  • Create credential systems

Example:

import { deriveSecretScalar, derivePublicKey, signMessage, verifySignature } from "@zk-kit/eddsa-poseidon"

const privateKey = deriveSecretScalar("secret")
const publicKey = derivePublicKey(privateKey)
const signature = signMessage(privateKey, message)
const isValid = verifySignature(message, signature, publicKey)

→ EdDSA-Poseidon on npm | GitHub

Poseidon Cipher

Use for: Encryption/decryption for ZK-friendly data

npm i @zk-kit/poseidon-cipher

Choose Poseidon Cipher when:

  • Need to encrypt data
  • Data used in ZK circuits
  • Privacy-preserving storage
  • Encrypted messaging

Example:

import { poseidonEncrypt, poseidonDecrypt } from "@zk-kit/poseidon-cipher"

const ciphertext = poseidonEncrypt(plaintext, key, nonce)
const decrypted = poseidonDecrypt(ciphertext, key, nonce, length)

→ Poseidon Cipher on npm | GitHub

Baby JubJub

Use for: Low-level elliptic curve operations

npm i @zk-kit/baby-jubjub

Choose Baby JubJub when:

  • Need curve arithmetic
  • Building custom cryptography
  • Implementing protocols
  • Research and development

Example:

import { Point } from "@zk-kit/baby-jubjub"

const point = Point.fromPrivateKey(privateKey)
const doubled = point.double()
const sum = point.add(otherPoint)

→ Baby JubJub on npm | GitHub

Poseidon Proof

Use for: Generate and verify zk-SNARK proofs

npm i @zk-kit/poseidon-proof

Choose Poseidon Proof when:

  • Need SNARK proofs
  • Verify Poseidon hashes
  • Build proof systems
  • Custom circuits

→ Poseidon Proof on npm | GitHub

Utilities Selection

Utils

Use for: Field operations, conversions, and utilities

npm i @zk-kit/utils

Choose Utils when:

  • Need field arithmetic
  • Convert between formats
  • Work with scalars
  • Perform modular operations

Example:

import { F1Field } from "@zk-kit/utils"

const field = new F1Field(prime)
const sum = field.add(a, b)
const product = field.mul(a, b)

→ Utils on npm | GitHub

Logical Expressions

Use for: Boolean logic in zero-knowledge

npm i @zk-kit/logical-expressions

Choose Logical Expressions when:

  • Need AND/OR/NOT logic
  • Complex boolean conditions
  • Circuit optimization
  • Policy enforcement

→ Logical Expressions on npm | GitHub

Common Combinations

Anonymous Voting

npm i @zk-kit/imt
# + peer dependencies (see npm page)

Packages:

  • IMT for voter membership
  • Hash function (peer dependency)

Example: See Semaphore Protocol and MACI

Private Airdrops

npm i @zk-kit/imt @zk-kit/eddsa-poseidon
# + peer dependencies (see npm pages)

Packages:

  • IMT for eligible addresses
  • EdDSA-Poseidon for signatures

Example: Check the Your First Proof guide

Identity System

npm i @zk-kit/imt @zk-kit/eddsa-poseidon @zk-kit/poseidon-cipher
# + peer dependencies (see npm pages)

Packages:

  • IMT for identity groups
  • EdDSA-Poseidon for credentials
  • Poseidon Cipher for encrypted data

Example: See Worldcoin and Iden3

State Management

npm i @zk-kit/smt @zk-kit/utils crypto-js

Packages:

  • SMT for key-value state
  • Utils for field operations

Example: See Iden3 implementation

Performance Comparison

Tree Operations (1M leaves)

OperationIMTLeanIMTSMT
Insert2.1ms2.5ms3.0ms
Update1.8ms2.3ms2.8ms
Delete1.8ms2.3ms2.5ms
Proof Gen8ms10ms12ms
Verify3ms3ms4ms
Memory1GB100MB500MB

Cryptography Operations

OperationTimeNotes
Sign (EdDSA)5msMessage signing
Verify (EdDSA)8msSignature verification
Encrypt (Poseidon)3msPer block
Decrypt (Poseidon)3msPer block
Point Add (BabyJubJub)0.5msElliptic curve
Scalar Mul (BabyJubJub)2msPoint multiplication

Migration Paths

From IMT to LeanIMT

// Before (IMT)
import { IMT } from "@zk-kit/imt"
const tree = new IMT(poseidon2, 16, 0, 2)

// After (LeanIMT)
import { LeanIMT } from "@zk-kit/lean-imt"
const tree = new LeanIMT((a, b) => poseidon2([a, b]))

See the LeanIMT package for details.

From Traditional to ZK

// Before (Traditional storage)
const users = new Set()
users.add(userId)

// After (ZK-enabled)
import { IMT } from "@zk-kit/imt"
const users = new IMT(poseidon2, 16, 0, 2)
users.insert(commitment)

Still Unsure?

Ask Yourself

  1. What am I building?

    • Voting → IMT
    • Airdrop → IMT + EdDSA
    • State → SMT
    • Mobile → LeanIMT
  2. What constraints do I have?

    • Memory limited → LeanIMT
    • Need speed → IMT
    • Need key-value → SMT
  3. What features do I need?

    • Just membership → IMT
    • Non-membership → SMT
    • Signatures → EdDSA-Poseidon
    • Encryption → Poseidon Cipher

Get Help

Next Steps