http://docker:8085Each custody wallet (hot, warm, cold) gets an ML-DSA-65 keypair. Private key stored in HSM; address derived from public key.
ML-DSA-65 (FIPS 204)Every deposit, withdrawal, and transfer is signed with provider.sign(). Signature proves the exchange authorized the movement.
ML-DSA-65 (FIPS 204)Complete transaction log with signatures. Auditors verify with provider.verify() using the custody wallet's public key.
ML-DSA-65 (FIPS 204)This service demonstrates quantum-safe exchange operations — the same patterns you'll implement using the Qudo JNI provider in your custody / exchange platform.
Custody wallet creation: provider.generateKeyPair("ML-DSA-65") — one keypair per custody wallet
Transaction authorization: provider.sign(txEnvelope, custodyPrivKey, "ML-DSA-65") on every deposit, withdrawal, transfer
Audit: Signed transaction ledger with ML-DSA-65 signatures — quantum-safe non-repudiation for compliance
/api/exchange/create-custody-wallet
Create a custody wallet
/api/exchange/deposit
Deposit assets to custody wallet
/api/exchange/withdraw
Withdraw assets from custody wallet
/api/exchange/transfer
Transfer between custody wallets (hot/warm/cold)
/api/exchange/wallets
List all custody wallets
/api/exchange/transactions
View signed transaction ledger
/api/exchange/health
Service health
Migrate your crypto exchange / custody platform to quantum-safe signatures. Use this playground to try PQC custody operations, then use the Qudo JNI provider in your exchange backend.
Each custody wallet (hot, warm, cold) has an ML-DSA-65 keypair generated via provider.generateKeyPair(). Private keys stored in HSM; public keys used to derive wallet addresses.
Every deposit, withdrawal, and internal transfer is signed with provider.sign(). Signature proves the exchange authorized the movement — quantum-safe non-repudiation for auditors.
Replace your ECDSA custody key management with Qudo JNI. Your wallet hierarchy (hot/warm/cold) and risk policies stay the same.
import com.qudo.crypto.QudoCrypto;
import com.qudo.crypto.QudoKeyPair;
QudoCrypto provider = QudoCrypto.create();
// ============================================================
// 1. Create custody wallets (one keypair per wallet tier)
// ============================================================
QudoKeyPair hotKeys = provider.generateKeyPair("ML-DSA-65"); // daily operations
QudoKeyPair warmKeys = provider.generateKeyPair("ML-DSA-65"); // weekly settlement
QudoKeyPair coldKeys = provider.generateKeyPair("ML-DSA-65"); // cold storage
// Store privKeyPem in HSM; publish pubKey + derived address
// ============================================================
// 2. Sign a withdrawal (authorization by custody wallet)
// ============================================================
String txJson = "{\"type\":\"withdrawal\",\"wallet\":\"hot-1\",\"amount\":\"1.5 BTC\",\"to\":\"0xabc\",\"nonce\":42}";
byte[] txEnvelope = txJson.getBytes();
byte[] signature = provider.sign(txEnvelope, hotKeys.getPrivateKeyPem(), "ML-DSA-65");
// Log to audit ledger: txEnvelope + signature + hotKeys.getPublicKeyPem()
// ============================================================
// 3. Auditor verifies historical transactions
// ============================================================
boolean valid = provider.verify(txEnvelope, signature,
hotKeys.getPublicKeyPem(), "ML-DSA-65");
// Quantum-safe proof the exchange authorized this withdrawal
provider.close();
| Operation | ML-DSA-65 (Qudo JNI) | ECDSA (classical) |
|---|---|---|
| Custody wallet creation (once) | ~55ms | ~3ms |
| Transaction signing (per tx) | ~10ms | <1ms |
| Signature verification (audit) | ~5ms | <1ms |
| Signature size | 3,309 bytes | 64 bytes |
Cause: Custody private keys are your highest-value secret. Storing in JVM heap makes them vulnerable to memory dumps.
Fix: Store provider.generateKeyPair() output in HSM. Load only the reference, sign through HSM boundary.
Cause: Without a nonce, signed withdrawal requests can be replayed.
Fix: Include monotonic nonce (per-wallet counter) and timestamp in txEnvelope before signing.
A: Yes. Generate an independent ML-DSA-65 keypair per custody tier. Hot wallet compromises don't expose warm/cold signatures.
A: Publish the custody wallet public keys. Auditors run provider.verify(txEnvelope, sig, pubKey, "ML-DSA-65") on every transaction in the ledger. ML-DSA-65 remains secure even after quantum computers are built.
Analyze any endpoint's cryptographic configuration. Enter a host:port to scan its TLS setup and identify what's quantum-safe vs what needs migration.