Skip to main content
voltaire-effect provides Effect-based wrappers for all cryptographic operations: hashing, signatures, encryption, key derivation, and zero-knowledge proofs. These wrap the high-performance crypto from Voltaire.

Combined Layers

For convenience, use CryptoLive (production) or CryptoTest (testing) to provide the non-native crypto services at once. For native HDWallet support, use CryptoLiveNative from voltaire-effect/native.

CryptoLive

Production layer with all cryptographic services:
import { Effect } from 'effect'
import { CryptoLive, KeccakService, Secp256k1Service } from 'voltaire-effect/crypto'

const program = Effect.gen(function* () {
  const keccak = yield* KeccakService
  const secp = yield* Secp256k1Service
  
  const hash = yield* keccak.hash(new Uint8Array([1, 2, 3]))
  const { publicKey, privateKey } = yield* secp.generateKeyPair()
  
  return { hash, publicKey }
}).pipe(Effect.provide(CryptoLive))

await Effect.runPromise(program)
Included services:
  • Keccak256, SHA256, Blake2, RIPEMD-160 (hashing)
  • Secp256k1, Ed25519, P256, BLS12-381 (signatures)
  • ChaCha20-Poly1305 (encryption)
  • HDWallet, BIP-39, Keystore (key derivation)
  • BN254, KZG (zero-knowledge)
  • HMAC, EIP-712 (utilities)

CryptoTest

Mock layer for unit testing. Returns deterministic values without cryptographic overhead:
import { CryptoTest, KeccakService } from 'voltaire-effect/crypto'

const testProgram = Effect.gen(function* () {
  const keccak = yield* KeccakService
  const hash = yield* keccak.hash(new Uint8Array([1, 2, 3]))
  // Returns zero-filled array for predictable testing
}).pipe(Effect.provide(CryptoTest))

Individual Services

Import only what you need for smaller bundles:
import { KeccakLive, KeccakService } from 'voltaire-effect/crypto/Keccak256'
import { Secp256k1Live, Secp256k1Service } from 'voltaire-effect/crypto/Secp256k1'
import { Effect, Layer } from 'effect'

// Compose layers once
const CryptoLayer = Layer.mergeAll(KeccakLive, Secp256k1Live)

const program = Effect.gen(function* () {
  const keccak = yield* KeccakService
  const hash = yield* keccak.hash(data)
}).pipe(Effect.provide(CryptoLayer))

Service Categories

Hashing

ServiceDescription
Keccak256Ethereum’s primary hash (SHA3-256 variant)
SHA256Standard SHA-256
Blake2Blake2b and Blake2s
RIPEMD-160For Bitcoin-style addresses

Signatures

ServiceDescription
Secp256k1Ethereum signatures (ECDSA)
Ed25519EdDSA signatures
P256NIST P-256 / secp256r1
BLS12-381BLS signatures (beacon chain)

Encryption

ServiceDescription
AES-GCMSymmetric encryption
ChaCha20-Poly1305Modern symmetric encryption
X25519Key exchange (ECDH)

Key Derivation

ServiceDescription
HDWalletBIP-32/44 hierarchical deterministic keys
BIP-39Mnemonic phrase generation
KeystoreEncrypted key storage (Web3 Secret Storage)
HMACKeyed-hash message authentication

Zero Knowledge

ServiceDescription
BN254BN254 curve for ZK proofs
KZGKZG commitments (EIP-4844 blobs)

Utilities

ServiceDescription
EIP-712Typed data hashing and signing
SignersHigh-level signing interface
ModExpModular exponentiation (precompile)

Layer Composition

Compose individual layers as needed:
import { Layer } from 'effect'
import { KeccakLive } from 'voltaire-effect/crypto/Keccak256'
import { Secp256k1Live } from 'voltaire-effect/crypto/Secp256k1'
import { HDWalletLive } from 'voltaire-effect/native'

// Custom subset of crypto services
const MyCrypto = Layer.mergeAll(
  KeccakLive,
  Secp256k1Live,
  HDWalletLive
)

program.pipe(Effect.provide(MyCrypto))

Testing Pattern

Use *Test layers for unit tests:
import { describe, it, expect } from 'vitest'
import { Effect } from 'effect'
import { CryptoTest, KeccakService } from 'voltaire-effect/crypto'

describe('MyHash', () => {
  it('should hash data', async () => {
    const result = await Effect.runPromise(
      Effect.gen(function* () {
        const keccak = yield* KeccakService
        return yield* keccak.hash(new Uint8Array([1, 2, 3]))
      }).pipe(Effect.provide(CryptoTest))
    )
    
    // Test layers return deterministic values
    expect(result).toHaveLength(32)
  })
})

See Also