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
@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
Important Requirements:
SharedArrayBuffer Support Required: The multi-threaded WASM implementation requires SharedArrayBuffer
to be enabled, which needs Cross-Origin Isolation headers.
For Vite projects, add this configuration:
// vite.config.ts
import { defineConfig } from "vite";
function crossOriginIsolationMiddleware(_, res, next) {
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
next();
}
const setCors = () => ({
name: "configure-server",
configureServer: (server) => {
server.middlewares.use(crossOriginIsolationMiddleware);
},
configurePreviewServer: (server) => {
server.middlewares.use(crossOriginIsolationMiddleware);
}
});
export default defineConfig({
plugins: [
// ... your other plugins
setCors()
],
// ... rest of your config
});
For production deployments, ensure your web server sends these headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
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
@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)
@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