Skip to content

sapogeth/web3-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@stvor/web3

Post-quantum end-to-end encryption for TON Web3.

The first E2EE library built for Web3 that is resistant to quantum computers — today.

Documentation: pqc.stvor.xyz

npm install @stvor/web3

Tests NIST FIPS 203 Zero dependencies TON


Why

Every message sent today can be stored and decrypted later by a quantum computer. This is called a "Store Now, Decrypt Later" attack. It is happening now.

@stvor/web3 uses ML-KEM-768 (NIST FIPS 203, finalized 2024) combined with classical P-256 X3DH in a hybrid scheme. Breaking the encryption requires breaking both — which no computer, classical or quantum, can do simultaneously.

Features

  • Hybrid post-quantum X3DH — ML-KEM-768 + P-256, HKDF-combined
  • Double Ratchet — forward secrecy and break-in recovery (Signal Protocol)
  • TON wallet identityuserId = wallet address. No accounts, no passwords
  • Account Abstraction — ERC-4337 (Safe, Coinbase, Biconomy, ZeroDev) + TON Wallet v5
  • UserOperation binding — cryptographically binds E2EE session to a specific AA op
  • On-chain key registry — public keys stored in a FunC smart contract
  • TON Storage delivery — encrypted messages stored off-chain, decentralised
  • Zero dependencies — 0 npm runtime dependencies. WASM crypto core (Rust)
  • NIST verified — 53 official ACVTS test vectors (ECDH, ECDSA, AES-GCM, HKDF)

Crypto stack

Identity:    TON wallet address (signed with Ed25519)
Key exchange: Hybrid X3DH
               ├── P-256 ECDH       (classical, NIST)
               └── ML-KEM-768       (post-quantum, NIST FIPS 203)
               └── HKDF-SHA256 combine → shared secret
Sessions:    Double Ratchet (Signal Protocol)
Encryption:  AES-256-GCM
Signing:     ECDSA P-256 / SHA-256
Implementation: Rust → WASM (270 KB, zero C dependencies)

Quick start

import { StvorWeb3 } from '@stvor/web3';
import initWasm from '@stvor/web3/wasm';

// 1. Load WASM crypto engine
const wasm = await initWasm();

// 2. Connect with TON wallet (TonConnect)
const alice = await StvorWeb3.connect({
  provider: tonConnectProvider,       // TonConnect wallet
  contractAddress: 'EQD...',          // stvor_registry on TON testnet
  tonApiUrl: 'https://testnet.toncenter.com/api/v2',
  wasm,
});

// 3. Listen for incoming messages
alice.onMessage(msg => {
  console.log(`From ${msg.from}:`, msg.data);
});

// 4. Send a post-quantum encrypted message
await alice.send('0:bob_address...', {
  text: 'Hello, quantum-safe Web3!'
});

// 5. Disconnect when done
await alice.disconnect();

Account Abstraction

Works with any EIP-1193 provider — EOA wallet or ERC-4337 smart wallet (Safe, Coinbase, Biconomy, ZeroDev). Also supports TON Wallet v5 extensions.

import { StvorAA } from '@stvor/web3';
import initWasm from '@stvor/web3/wasm';

const wasm = await initWasm();

// ── EVM — ERC-4337 (Safe, Coinbase Smart Wallet, ZeroDev, Biconomy…) ──
const client = await StvorAA.connectEVM({
  provider: window.ethereum,  // any EIP-1193 provider
  chainId: 1,
  wasm,
});
await client.send('0xrecipient...', { text: 'gm from AA wallet!' });

// ── TON — Wallet v5 ──
const tonClient = await StvorAA.connectTON({
  provider: tonConnectProvider,
  wasm,
});

// Bind E2EE session to a UserOperation (ERC-4337)
const binding = client.bindUserOp(userOpHash, sessionRootKey);
// binding.userOpHash / .identitySig / .sessionCommitment

// Verify peer's binding
const ok = client.verifyUserOp(binding, peerIdentityKey, sessionRootKey);

// Sign TON v5 extension body
const ext = tonClient.signTonExtension('deadbeef0102');
const valid = tonClient.verifyTonExtension(ext, peerIk);

How identity derivation works:

personal_sign("STVOR-AA-EVM-v1:{chainId}:{address}")
  → HKDF(sig, msg, "IK",  32)  →  P-256 identity keypair
  → HKDF(sig, msg, "SPK", 32)  →  P-256 signed pre-key
  → wasm_mlkem_keygen()         →  ML-KEM-768 keypair

Same signature always produces the same keys — deterministic and reproducible across sessions.


Installation

npm install @stvor/web3

Requirements: Browser or Node.js ≥ 18 with Web Crypto API and WebAssembly support (available everywhere since 2022).


API reference

StvorWeb3.connect(config)

Creates a client connected to the TON network.

const client = await StvorWeb3.connect({
  provider: TonConnectProvider,   // TON Connect wallet provider
  contractAddress: string,        // stvor_registry contract address
  tonApiUrl: string,              // TonCenter API endpoint
  wasm: WasmModule,               // initialized WASM module
  tonApiKey?: string,             // optional TonCenter API key
  pollIntervalMs?: number,        // message poll interval (default: 5000)
  pqc?: boolean,                  // enable hybrid PQC (default: true)
});

client.send(to, data)

Sends a post-quantum encrypted message to a TON wallet address.

await client.send('0:recipient_address...', {
  text: 'Hello!',
  // any JSON-serializable data
});

client.onMessage(handler)

Registers a handler for incoming messages. Returns an unsubscribe function.

const unsub = client.onMessage(msg => {
  console.log(msg.from);       // TON address
  console.log(msg.data);       // decrypted payload
  console.log(msg.timestamp);  // Date
  console.log(msg.id);         // message ID
});

// Later:
unsub();

client.address

The TON wallet address of this client.

console.log(client.address); // "0:abc123..."

client.chain

Network: 'mainnet' or 'testnet'.

client.disconnect()

Stops polling and clears session state.


Low-level WASM API

For advanced use cases, the Rust crypto primitives are directly accessible:

import initWasm, {
  WasmKeyPair,
  WasmSession,
  wasm_mlkem_keygen,
  wasm_mlkem_encaps,
  wasm_mlkem_decaps,
  wasm_hybrid_initiate,
  wasm_hybrid_respond,
  wasm_ec_sign,
  wasm_ec_verify,
  wasm_hkdf,
} from '@stvor/web3/wasm';

const wasm = await initWasm();

// ML-KEM-768 key generation
const { ek, dk } = JSON.parse(wasm_mlkem_keygen());
// ek = 1184-byte encapsulation key (base64url)
// dk = 64-byte decapsulation key seed (base64url)

// Encapsulate shared secret
const { ct, ss } = JSON.parse(wasm_mlkem_encaps(ek));

// Decapsulate
const ss2 = wasm_mlkem_decaps(dk, ct);
// ss === ss2

// Hybrid X3DH session
const aliceIK  = new WasmKeyPair();
const aliceSPK = new WasmKeyPair();
const bobIK    = new WasmKeyPair();
const bobSPK   = new WasmKeyPair();
const bobPqc   = JSON.parse(wasm_mlkem_keygen());

// Alice initiates
const { session_json, mlkem_ct } = JSON.parse(
  wasm_hybrid_session_initiate(aliceIK, aliceSPK, bobIK.public_key, bobSPK.public_key, bobPqc.ek)
);
const alice = WasmSession.from_json(session_json);

// Bob responds
const bob = wasm_hybrid_session_respond(
  bobIK, bobSPK, aliceIK.public_key, aliceSPK.public_key, bobPqc.dk, mlkem_ct
);

// Encrypted messaging
const ct2 = alice.encrypt(new TextEncoder().encode('gm'));
const pt  = bob.decrypt(ct2);
// new TextDecoder().decode(pt) === 'gm'

Smart contract

The stvor_registry FunC contract stores public keys on-chain and tracks message bag IDs.

Testnet address: EQD... (deploy with node contracts/deploy.mjs)

ABI:

Method Type Description
register_keys internal Store IK + SPK + SIG + ML-KEM EK
store_message internal Record a TON Storage bag ID
delete_message internal Remove a bag ID (recipient only)
get_keys(addr) get-method Read public keys for an address
get_messages(addr) get-method List pending message bag IDs
get_message_count(addr) get-method Count pending messages

Security

Hybrid PQC scheme

shared_key = HKDF-SHA256(
  ikm  = ecdh_sk ‖ mlkem_ss,
  salt = 0x00...00,
  info = "STVOR-HYBRID-v1"
)

This is secure if either ECDH (P-256) or ML-KEM-768 is secure. An attacker must break both simultaneously — impossible with any known classical or quantum algorithm.

NIST ACVTS verification

All cryptographic primitives are verified against official NIST test vectors:

Algorithm Standard Vectors
P-256 ECDH NIST KAS ECC CDH 25
ECDSA P-256/SHA-256 NIST FIPS 186-3 SigVer 15
AES-256-GCM NIST SP 800-38D 21
HKDF-SHA256 RFC 5869 (NIST SP 800-56C) 3

Forward secrecy

The Double Ratchet protocol ensures that compromising a session key does not expose past messages. Each message uses a fresh symmetric key derived from the ratchet chain.

Key zeroization

All private key material is zeroed from memory after use via the zeroize crate.


Comparison

@stvor/web3 XMTP Waku Signal (libsignal)
Post-quantum (ML-KEM-768)
TON wallet identity
Double Ratchet
On-chain key registry
Zero npm dependencies
NIST ACVTS verified
Rust WASM crypto core

Project structure

stvor-web3/
├── crypto-core/          Rust crypto engine
│   └── src/
│       ├── crypto.rs     P-256 ECDH/ECDSA, AES-256-GCM, HKDF, HMAC
│       ├── pqc.rs        ML-KEM-768 (NIST FIPS 203)
│       ├── ratchet.rs    X3DH + Double Ratchet session
│       ├── wasm.rs       WASM bindings (wasm-bindgen)
│       └── nist_tests.rs NIST ACVTS test vectors
│
├── sdk/
│   ├── wasm/             Compiled WASM + TypeScript types (270 KB)
│   └── src/
│       ├── wallet.ts     TON wallet → E2EE identity derivation
│       ├── ton-storage.ts TON Storage + contract client
│       ├── stvor.ts      Main client (StvorWeb3)
│       └── index.ts      Public API exports
│
└── contracts/
    ├── stvor_registry.fc FunC smart contract
    ├── StvorRegistry.ts  TypeScript wrapper
    └── deploy.mjs        Testnet deployment script

Deploy contract (testnet)

cd contracts
npm install

# Set your wallet mnemonic
export STVOR_MNEMONIC="word1 word2 ... word24"

# Deploy to TON testnet
node deploy.mjs

# Output:
# Contract address: EQD...
# ✓ Deployed successfully!

Get testnet TON from @testgiver_ton_bot.


Contributing

# Run all tests (53 total)
cd crypto-core && cargo test        # 28 Rust tests (incl. NIST vectors)
cd sdk && node --experimental-wasm-modules --import tsx/esm src/__tests__/wasm.test.ts  # 17 WASM tests
cd contracts && node --import tsx/esm tests/registry.test.ts  # 8 contract tests

# Rebuild WASM after Rust changes
cd crypto-core && wasm-pack build --target web --out-dir ../sdk/wasm

License

MIT — stvor.xyz


Docs: pqc.stvor.xyz · npm: @stvor/web3 · TON: testnet

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors