TypeScript API Reference

Complete API documentation for MetaMUI Crypto Primitives in TypeScript/JavaScript.

Installation

npm install @metamui/crypto
# or
yarn add @metamui/crypto
# or
pnpm add @metamui/crypto

Quick Start

import { Ed25519, ChaCha20Poly1305, Blake3, Argon2 } from '@metamui/crypto';

// Generate keypair
const keypair = await Ed25519.generateKeypair();

// Sign message
const message = new TextEncoder().encode("Hello");
const signature = await Ed25519.sign(message, keypair.privateKey);

// Verify signature
const isValid = await Ed25519.verify(signature, message, keypair.publicKey);

API Documentation

For detailed API documentation, see:

Type Definitions

All functions include complete TypeScript definitions:

interface KeyPair {
  publicKey: Uint8Array;
  privateKey: Uint8Array;
}

interface EncryptionResult {
  ciphertext: Uint8Array;
  nonce: Uint8Array;
  tag?: Uint8Array;
}

type HashAlgorithm = 'sha256' | 'sha512' | 'blake2b' | 'blake3';

Available Modules

Hash Functions

import { SHA256, SHA512, Blake2b, Blake3, SHAKE256 } from '@metamui/crypto';

// Simple hashing
const hash = await SHA256.hash(data);
const hash = await Blake3.hash(data);

// Streaming hash
const hasher = Blake3.create();
hasher.update(chunk1);
hasher.update(chunk2);
const hash = hasher.finalize();

Digital Signatures

import { Ed25519, Sr25519, Dilithium, Falcon512 } from '@metamui/crypto';

// Ed25519
const keypair = await Ed25519.generateKeypair();
const signature = await Ed25519.sign(message, keypair.privateKey);
const isValid = await Ed25519.verify(signature, message, keypair.publicKey);

// Post-quantum signatures
const pqKeypair = await Dilithium.generateKeypair();
const pqSignature = await Dilithium.sign(message, pqKeypair.privateKey);

Encryption

import { ChaCha20Poly1305, AES256, ARIA256 } from '@metamui/crypto';

// ChaCha20-Poly1305
const key = await ChaCha20Poly1305.generateKey();
const encrypted = await ChaCha20Poly1305.encrypt(plaintext, key);
const decrypted = await ChaCha20Poly1305.decrypt(
  encrypted.ciphertext,
  encrypted.nonce,
  key
);

// AES-256-GCM
const aesKey = await AES256.generateKey();
const aesEncrypted = await AES256.encrypt(plaintext, aesKey);

Key Exchange

import { X25519, MLKem768 } from '@metamui/crypto';

// X25519 ECDH
const alice = await X25519.generateKeypair();
const bob = await X25519.generateKeypair();
const sharedSecret = await X25519.computeSharedSecret(
  alice.privateKey,
  bob.publicKey
);

// Post-quantum KEM
const kemKeypair = await MLKem768.generateKeypair();
const { ciphertext, sharedSecret } = await MLKem768.encapsulate(
  kemKeypair.publicKey
);

Key Derivation

import { Argon2, PBKDF2, HKDF } from '@metamui/crypto';

// Password hashing
const salt = Argon2.generateSalt();
const hash = await Argon2.hash(password, salt, {
  memory: 256 * 1024, // 256MB
  iterations: 4,
  parallelism: 2
});

// Key derivation
const key = await HKDF.derive(inputKey, {
  salt,
  info: new TextEncoder().encode("encryption key"),
  length: 32
});

Browser vs Node.js

Browser

import { initializeWebCrypto } from '@metamui/crypto';

// Initialize with Web Crypto API
await initializeWebCrypto();

// Use SubtleCrypto for better performance
const key = await crypto.subtle.generateKey(
  { name: 'AES-GCM', length: 256 },
  true,
  ['encrypt', 'decrypt']
);

Node.js

import { initializeNodeCrypto } from '@metamui/crypto';
import { webcrypto } from 'crypto';

// Initialize with Node.js crypto
await initializeNodeCrypto(webcrypto);

Async/Await Support

All CPU-intensive operations are async:

// Async operations
const hash = await Blake3.hash(largeData);
const keypair = await Ed25519.generateKeypair();
const encrypted = await ChaCha20Poly1305.encrypt(data, key);

// Parallel operations
const results = await Promise.all([
  Blake3.hash(data1),
  Blake3.hash(data2),
  Blake3.hash(data3)
]);

Error Handling

import { CryptoError, InvalidKeyError, DecryptionError } from '@metamui/crypto';

try {
  const decrypted = await ChaCha20Poly1305.decrypt(
    ciphertext,
    nonce,
    key
  );
} catch (error) {
  if (error instanceof DecryptionError) {
    console.error('Decryption failed:', error.message);
  } else if (error instanceof InvalidKeyError) {
    console.error('Invalid key:', error.message);
  } else if (error instanceof CryptoError) {
    console.error('Crypto error:', error.message);
  }
}

Tree Shaking

The library supports tree shaking for optimal bundle size:

// Only imports what you use
import { Ed25519 } from '@metamui/crypto/signatures';
import { Blake3 } from '@metamui/crypto/hashes';
import { ChaCha20Poly1305 } from '@metamui/crypto/ciphers';

Web Workers

Offload crypto operations to Web Workers:

import { createCryptoWorker } from '@metamui/crypto/worker';

const worker = createCryptoWorker();

// Run in worker
const hash = await worker.hash('blake3', data);
const signature = await worker.sign('ed25519', message, privateKey);

// Clean up
worker.terminate();

React Hooks

import { useCrypto } from '@metamui/crypto/react';

function MyComponent() {
  const { encrypt, decrypt, isReady } = useCrypto();
  
  const handleEncrypt = async (data: string) => {
    if (!isReady) return;
    
    const encrypted = await encrypt(data);
    // Store encrypted data
  };
}

Examples

Secure Storage

class SecureStorage {
  private key: Uint8Array;
  
  constructor(password: string) {
    const salt = localStorage.getItem('salt') || Argon2.generateSalt();
    this.key = await Argon2.deriveKey(password, salt, 32);
  }
  
  async store(key: string, value: any): Promise<void> {
    const data = JSON.stringify(value);
    const encrypted = await AES256.encrypt(
      new TextEncoder().encode(data),
      this.key
    );
    
    localStorage.setItem(key, JSON.stringify({
      ciphertext: Array.from(encrypted.ciphertext),
      nonce: Array.from(encrypted.nonce)
    }));
  }
  
  async retrieve(key: string): Promise<any> {
    const stored = JSON.parse(localStorage.getItem(key) || 'null');
    if (!stored) return null;
    
    const decrypted = await AES256.decrypt(
      new Uint8Array(stored.ciphertext),
      new Uint8Array(stored.nonce),
      this.key
    );
    
    return JSON.parse(new TextDecoder().decode(decrypted));
  }
}

End-to-End Encryption

class E2EEncryption {
  static async encryptMessage(
    message: string,
    recipientPublicKey: Uint8Array
  ): Promise<EncryptedMessage> {
    // Generate ephemeral keypair
    const ephemeral = await X25519.generateKeypair();
    
    // Compute shared secret
    const sharedSecret = await X25519.computeSharedSecret(
      ephemeral.privateKey,
      recipientPublicKey
    );
    
    // Derive encryption key
    const encKey = await HKDF.derive(sharedSecret, {
      info: new TextEncoder().encode("encryption"),
      length: 32
    });
    
    // Encrypt message
    const encrypted = await ChaCha20Poly1305.encrypt(
      new TextEncoder().encode(message),
      encKey
    );
    
    return {
      ephemeralPublicKey: ephemeral.publicKey,
      ciphertext: encrypted.ciphertext,
      nonce: encrypted.nonce
    };
  }
}

Performance Tips

  1. Use streaming for large data:
    const hasher = Blake3.create();
    for (const chunk of chunks) {
      hasher.update(chunk);
    }
    const hash = hasher.finalize();
    
  2. Batch operations:
    const results = await Ed25519.batchVerify(
      signatures,
      messages,
      publicKeys
    );
    
  3. Reuse instances:
    const cipher = new ChaCha20Poly1305(key);
    for (const data of dataset) {
      const encrypted = await cipher.encrypt(data);
    }
    

See Also