v2.0.1 · MIT License

PASETO for browsers,
powered by WebAssembly

A Rust implementation of Platform-Agnostic Security Tokens compiled to WASM. Bring v4 and v3 PASETO support to any JavaScript environment — browsers and Node.js alike.

$ pnpm add paseto-wasm
Quick Start → API Reference
example.js

import init, * as v4 from 'paseto-wasm';


// Initialize WASM module

await init();


// Generate encryption key

const key = v4.generate_v4_local_key();


// Encrypt & decrypt

const token = v4.encrypt_v4_local(key, { user: 'alice' });

const plain = v4.decrypt_v4_local(key, token);


JOSE done right

PASETO fixes the design flaws in JWT, JWE, and JWS. No algorithm confusion, no padding oracle attacks — just secure tokens that work.

WebAssembly Performance

Rust compiled to WASM runs near-native speed in browsers. No JavaScript crypto polyfills, no performance compromise.

v4 & v3 Support

XChaCha20-Poly1305 and Ed25519 for modern apps (v4). AES-256-CTR + HMAC-SHA384 for FIPS environments (v3).

PASERK Key Serialization

Standardized key encoding with Key IDs (lid, pid, sid). Serialize, restore, and identify keys without exposing material.

Universal Runtime

Works in browsers via ES modules and in Node.js via CommonJS. One library, every JavaScript environment.

TypeScript Ready

Shipped with .d.ts type definitions. Full autocompletion in VS Code, no @types package needed.

Battle-Tested Core

Built on rusty-paseto, a mature Rust crate with comprehensive test vectors and cross-implementation validation.


WASM vs TypeScript performance

See how paseto-wasm compares head-to-head against paseto-ts for real-world PASETO operations — signing and verification, right in your browser.

Run the benchmark →

Open the interactive benchmark suite in your browser. Tests V4 Ed25519 sign + verify across multiple iterations with warmup. Results are computed live using tinybench.

paseto-wasm-benchmark-browser.achmadk.com ↗

Up and running in 30 seconds

Install, initialize, and encrypt your first token. That's it.

1

Install the package

Add to your project with npm, yarn, pnpm, or bun.

2

Initialize WASM

Call the default export before using any crypto methods. It loads the compiled Rust module.

3

Encrypt or Sign

Use local keys for symmetric encryption, or key pairs for asymmetric signing. Both v4 and v3 available.

full-example.js

import initV4, * as v4 from 'paseto-wasm';


// Initialize the WASM module first

await initV4();


// ── Symmetric: Local encryption ──

const localKey = v4.generate_v4_local_key();

const token = v4.encrypt_v4_local(localKey, {

 sub: 'user123',

 exp: Math.floor(Date.now() / 1000) + 3600

});

const decrypted = v4.decrypt_v4_local(localKey, token);


// ── Asymmetric: Public signing ──

const kp = v4.generate_v4_public_key_pair();

const signed = v4.sign_v4_public(kp.secret, { user: 'alice' });

const verified = v4.verify_v4_public(kp.public, signed);


// ── PASERK serialization ──

const paserk = v4.key_to_paserk_local(localKey);

const restored = v4.paserk_local_to_key(paserk);


Choose your algorithm

v4 for new applications. v3 when FIPS compliance is required.

PASETO v4 PASETO v3
Local Algorithm XChaCha20-Poly1305 AES-256-CTR + HMAC-SHA384
Public Algorithm Ed25519 P-384 + ECDSA
Local Key Size 32 bytes (64 hex) 32 bytes (64 hex)
Secret Key Size 64 bytes (128 hex) 48 bytes (96 hex)
Public Key Size 32 bytes (64 hex) 49 bytes (98 hex)
Use Case Modern applications Recommended FIPS-compliant environments

Core methods

Import v4 or v3 — the API surface is identical. Initialize WASM first, then call methods.

generate_v4_local_key()

Generates a cryptographically secure random key for symmetric encryption. Returns a 64-character hex string.

local
generate_v4_public_key_pair()

Generates an Ed25519 key pair. Returns an object with secret (128 hex) and public (64 hex).

public
encrypt_v4_local(key, message, footer?)

Encrypts using XChaCha20-Poly1305. Message can be a string or object. Returns v4.local.{payload} token.

local
decrypt_v4_local(key, token, footer?)

Decrypts a local token. Throws if key is invalid, token tampered, or wrong key used.

local
sign_v4_public(secret, message, footer?)

Signs using Ed25519. Message is visible — provides authentication and integrity, not secrecy.

public
verify_v4_public(public, token, footer?)

Verifies a public token. Throws if signature is invalid or key doesn't match.

public
key_to_paserk_local(key_hex)

Converts a local key to PASERK format: k4.local.{data}. Standardized key serialization.

paserk
get_local_key_id(key_hex)

Returns a key identifier in format k4.lid.{hash}. Identify keys without exposing material.

key-id

Dependencies

wasm-bindgen

Rust ↔ JavaScript communication

rusty-paseto

PASETO implementation in Rust