Cryptography Client

The Shielder SDK uses a modular cryptographic architecture where the main SDK depends on the shielder-sdk-crypto interface, which is implemented by various platform-specific packages. This design allows the same SDK to work across different environments while providing flexibility in how cryptographic operations are performed.

Architecture Overview

All cryptographic implementations in the Shielder ecosystem implement the CryptoClient interface defined in @cardinal-cryptography/shielder-sdk-crypto. This interface provides:

  • Field Element Representation: Scalar class for BN256 conversions to/from vanilla JS's types.

  • Cryptographic Types Definition: an interface for ZKP circuits and hashing backends.

The main shielder-sdk package accepts any implementation of this interface, making it environment-agnostic.

Available Implementations

1. @cardinal-cryptography/shielder-sdk-crypto-wasm

The full-featured WebAssembly implementation with local cryptographic operations.

Key Features:

  • Complete Local Implementation: All zero-knowledge proof generation happens locally in the browser, making it the most secure option.

  • Multi-threading Support: Can utilize Web Workers for faster proof generation

  • Production Ready: Fully tested and recommended for production deployments

Setup:

import { initWasmWorker } from "@cardinal-cryptography/shielder-sdk-crypto-wasm";

// Import circuit parameters and proving keys
import newAccountParamsUrl from "@cardinal-cryptography/shielder-sdk-crypto-wasm/keys/new_account/params.bin?url";
import newAccountPkUrl from "@cardinal-cryptography/shielder-sdk-crypto-wasm/keys/new_account/pk.bin?url";
import depositParamsUrl from "@cardinal-cryptography/shielder-sdk-crypto-wasm/keys/deposit/params.bin?url";
import depositPkUrl from "@cardinal-cryptography/shielder-sdk-crypto-wasm/keys/deposit/pk.bin?url";
import withdrawParamsUrl from "@cardinal-cryptography/shielder-sdk-crypto-wasm/keys/withdraw/params.bin?url";
import withdrawPkUrl from "@cardinal-cryptography/shielder-sdk-crypto-wasm/keys/withdraw/pk.bin?url";

// Fetch the required circuit parameters and proving keys
const newAccountParams = await fetch(newAccountParamsUrl).then((r) => r.bytes());
const newAccountPk = await fetch(newAccountPkUrl).then((r) => r.bytes());
const depositParams = await fetch(depositParamsUrl).then((r) => r.bytes());
const depositPk = await fetch(depositPkUrl).then((r) => r.bytes());
const withdrawParams = await fetch(withdrawParamsUrl).then((r) => r.bytes());
const withdrawPk = await fetch(withdrawPkUrl).then((r) => r.bytes());

// Initialize with multi-threading support
const cryptoClient = await initWasmWorker(
  "multi",
  { paramsBuf: newAccountParams, pkBuf: newAccountPk },
  { paramsBuf: depositParams, pkBuf: depositPk },
  { paramsBuf: withdrawParams, pkBuf: withdrawPk }
);

Trade-offs:

  • Pros: Maximum security, no external dependencies, production-ready, fastest proof generation

  • Cons: Large bundle size (~10-50MB), complex setup, requires downloading circuit parameters, multi-threading requires SharedArrayBuffer browser feature to be enabled.

Use Cases:

  • Production applications

  • Applications requiring maximum security

  • Environments where bundle size is not a primary concern

  • Applications that need offline cryptographic operations


2. @cardinal-cryptography/shielder-sdk-crypto-wasm-light

A lightweight WebAssembly implementation that uses Trusted Execution Environment (TEE) for remote proof generation.

Key Features:

  • Remote Proving + TEE Security: Zero-knowledge proofs are generated in AWS Nitro Enclaves with attestation verification, ensuring data is securely encrypted and not accessible to remote host operator.

  • Small Bundle Size: No circuit parameters or proving keys in the client

  • Simple Setup: Minimal configuration required

  • Alpha Stage: Currently in development, not recommended for production

Setup:

import { initWasmWorker } from "@cardinal-cryptography/shielder-sdk-crypto-wasm-light";

// PCR values for TEE attestation verification
const pcrs = new Map<string, string>(
  Object.entries({
    "0": "94b74422daddb8f503fcd69df064c7cde5d053001b9cd153c75ec34484283496a37e89c7287a00f467759a6863362b60",
    "1": "927e084e583f5c2d60a39e2b9cd9728bfb390aa9f83dee4b6ac768509850ba273ea8b019ccfbf3180eb18a2dd0c4a678",
    "2": "07c20c057d5c10cb732b273b7fa26a2b67e333344ccda49be939a6b7c5bed5e46f0b0703386dd2d0f6104a13a4894cb2",
  })
);

const cryptoClient = await initWasmWorker(
  "https://prover-server.test.blanksquare.dev",
  pcrs
);

Trade-offs:

  • Pros: Very small bundle size, simple setup, fast initial load

  • Cons: Alpha stage, requires network connectivity, depends on external TEE service, potential privacy implications

Use Cases:

  • Development and testing environments

  • Applications with strict bundle size requirements

  • Rapid prototyping


3. @cardinal-cryptography/shielder-sdk-crypto-mobile (React Native)

React Native implementation for mobile applications.

Key Features:

  • React Native Support: Native mobile app integration

  • Native Performance: Leverages device-native cryptographic operations

Setup:

import { RNCryptoClient } from '@cardinal-cryptography/shielder-sdk-crypto-mobile';
import { CryptoClient } from '@cardinal-cryptography/shielder-sdk-crypto';

const cryptoClient: CryptoClient = new RNCryptoClient();

Use Cases:

  • React Native mobile applications


Choosing the Right Implementation

For Production Web Applications:

Use @cardinal-cryptography/shielder-sdk-crypto-wasm

  • Maximum security with local proof generation

  • No external service dependencies

  • Battle-tested and production-ready

For Development/Testing:

Use @cardinal-cryptography/shielder-sdk-crypto-wasm-light

  • Quick setup and small bundle size

  • Good for rapid prototyping

  • Remember: Alpha stage, not for production

For Mobile Applications:

Use @cardinal-cryptography/shielder-sdk-crypto-mobile

  • Native React Native integration

  • Device-optimized performance

Integration with Shielder SDK

All implementations work seamlessly with the main Shielder SDK:

import { createShielderClient } from "@cardinal-cryptography/shielder-sdk";

// Use any CryptoClient implementation
const shielderClient = createShielderClient({
  // ... other config
  cryptoClient: await yourChosenCryptoClient, // Any implementation works here
});

Last updated