Triple Key API

Post-quantum multi-layer digital signatures combining Ed25519 + Dilithium-5 (ML-DSA-87) + FALCON-512 into a single unified signing and verification API. Three algorithms, one API call.

Ed25519 Dilithium-5 FALCON-512 Post-Quantum Secure v1.0

Overview

The Triple Key API generates keypairs, signs, and verifies using three independent signature algorithms in one call: Ed25519 (classical), Dilithium-5 / ML-DSA-87 (FIPS 204), and FALCON-512 (FN-DSA, FIPS 206 draft). A composite signature verifies only if all three layers pass, so an attacker must break three unrelated hardness assumptions at once. This is the signing primitive H33 uses to produce the portable 74-byte post-quantum attestation — the small, self-contained proof-of-signature that can be verified independently of H33 infrastructure.

Use it when you need a signature that stays trustworthy through the post-quantum transition and whose validity a third party can confirm without trusting your servers. Use a different H33 component when: you need to protect an existing API key or secret at point of use → H33-Key; you need to compute on data while it stays encrypted → FHE Platform; you need to prove a fact without revealing the underlying data → ZK Platform. To independently validate a signature, see Verification.

Authentication

All requests to the Triple Key API require an API key passed via the X-API-Key header. You can generate an API key from your dashboard.

HTTP Header
X-API-Key: h33_pk_your_api_key_here
i
Demo Key Available
Use h33_demo_triple_key_public for testing. Limited to 100 operations per day. Do not use in production.

Example Request

curl
curl -X POST https://api.h33.ai/api/v1/triple-key/generate \ -H "Content-Type: application/json" \ -H "X-API-Key: h33_pk_your_api_key_here" \ -d '{"label": "my-first-keypair"}'

Error Codes

The API uses standard HTTP status codes. All error responses include a JSON body with error and message fields.

Error Response Format
{ "error": "invalid_base64", "message": "The message_b64 field contains invalid base64 encoding.", "status": 400 }
Status Error Code Description
400 invalid_base64 Request contains malformed base64 data
400 key_not_found The specified key_id does not exist
400 invalid_security_level security_level must be standard, high, or critical
400 missing_field A required field is missing from the request body
400 key_revoked The specified key has been revoked
401 unauthorized Missing or invalid API key
500 internal Unexpected server error. Contact support if persistent

Generate Keypair

Sign Message

POST /api/v1/triple-key/sign 3 Credits

Sign a message with all three algorithms in a single API call. The message is signed with Ed25519, Dilithium-5, and FALCON-512 sequentially, producing a unified composite signature.

Request Body

Field Type Required Description
key_id string required The keypair identifier returned from /generate
message_b64 string required Base64-encoded message to sign (max 10MB)

Example Request

JSON
{ "key_id": "tk_9f8a7b6c5d4e3f2a1b0c", "message_b64": "SGVsbG8sIFRyaXBsZSBLZXkh" }

Response

Field Type Description
signature_b64 string Composite signature (base64). Contains Ed25519 + Dilithium + FALCON signatures concatenated
version string Signature format version (e.g. "1.0")
algorithm string Always "triple-key-v1"
key_version integer Key version used for signing (increments on rotation)
latency_us integer Server-side latency in microseconds

Example Response

JSON
{ "signature_b64": "MEUCIQC7...composite...base64...", "version": "1.0", "algorithm": "triple-key-v1", "key_version": 1, "latency_us": 1240 }

Verify Signature

POST /api/v1/triple-key/verify 1 Credit

Verify a Triple Key composite signature against a message. All three signature layers (Ed25519, Dilithium-5, FALCON-512) are verified independently. The signature is valid only if all three layers pass.

Request Body

Field Type Required Description
message_b64 string required Base64-encoded original message
signature_b64 string required Composite signature from /sign endpoint
ed25519_public_key string required Ed25519 public key (base64)
dilithium_public_key string required Dilithium-5 public key (base64)
falcon_public_key string required FALCON-512 public key (base64)

Example Request

JSON
{ "message_b64": "SGVsbG8sIFRyaXBsZSBLZXkh", "signature_b64": "MEUCIQC7...composite...base64...", "ed25519_public_key": "MCowBQYDK2VwAyEAGb1gauf...", "dilithium_public_key": "MIIFIDAHBgUrzg8D...", "falcon_public_key": "MIICIjANBgkqhkiG..." }

Response

Field Type Description
valid boolean true if all three layers verified successfully
algorithm string Always "triple-key-v1"
layers_verified array List of algorithms that passed verification
latency_us integer Server-side latency in microseconds

Example Response

JSON
{ "valid": true, "algorithm": "triple-key-v1", "layers_verified": [ "ed25519", "dilithium-5", "falcon-512" ], "latency_us": 890 }

Configure Rotation

POST /api/v1/triple-key/rotate/configure 2 Credits

Configure the automatic key rotation policy for a Triple Key keypair. Security level determines rotation frequency and whether NFT-binding is enabled for audit trails.

Request Body

Field Type Required Description
key_id string required The keypair identifier
security_level string required standard (90 days) | high (30 days) | critical (7 days)

Example Request

JSON
{ "key_id": "tk_9f8a7b6c5d4e3f2a1b0c", "security_level": "critical" }

Response

Field Type Description
status string Always "configured" on success
rotation_period_days integer Effective rotation period based on security level
nft_binding boolean Whether rotation events are anchored on-chain

Example Response

JSON
{ "status": "configured", "rotation_period_days": 7, "nft_binding": true }
!
Critical Security Level
The critical level rotates keys every 7 days and creates an on-chain NFT audit trail for each rotation event. This incurs additional blockchain transaction fees.

Rotation Status

GET /api/v1/triple-key/rotate/status Free

Check the current rotation status of a keypair. Returns whether the key needs rotation, the current version, and the next scheduled rotation date.

Query Parameters

Parameter Type Required Description
key_id string required The keypair identifier

Example Request

HTTP
GET /api/v1/triple-key/rotate/status?key_id=tk_9f8a7b6c5d4e3f2a1b0c HTTP/1.1 Host: api.h33.ai X-API-Key: h33_pk_your_api_key_here

Response

Field Type Description
key_id string The keypair identifier
key_version integer Current key version number
needs_rotation boolean true if the key has exceeded its rotation period
rotation_in_progress boolean true if a rotation is currently being executed
next_rotation string ISO 8601 timestamp of next scheduled rotation
last_rotated string ISO 8601 timestamp of most recent rotation

Example Response

JSON
{ "key_id": "tk_9f8a7b6c5d4e3f2a1b0c", "key_version": 3, "needs_rotation": false, "rotation_in_progress": false, "next_rotation": "2026-03-01T00:00:00Z", "last_rotated": "2026-02-22T08:30:00Z" }

Execute Rotation

POST /api/v1/triple-key/rotate/execute 5 Credits

Manually trigger an immediate key rotation. New key material is generated for all three algorithms. Previous key versions remain available for signature verification but can no longer sign new messages.

Request Body

Field Type Required Description
key_id string required The keypair identifier
reason string optional Reason for manual rotation (logged in audit trail)

Example Request

JSON
{ "key_id": "tk_9f8a7b6c5d4e3f2a1b0c", "reason": "Scheduled compliance rotation" }

Response

Field Type Description
status string "rotated" on success
rotation_id string Unique rotation event identifier
new_key_version integer The new key version number
ed25519_public_key string New Ed25519 public key (base64)
dilithium_public_key string New Dilithium-5 public key (base64)
falcon_public_key string New FALCON-512 public key (base64)
latency_us integer Server-side latency in microseconds

Example Response

JSON
{ "status": "rotated", "rotation_id": "rot_a1b2c3d4e5f6", "new_key_version": 4, "ed25519_public_key": "MCowBQYDK2VwAyEA...new...base64...", "dilithium_public_key": "MIIFIDAHBgUrzg8D...new...base64...", "falcon_public_key": "MIICIjANBgkqhkiG...new...base64...", "latency_us": 5130 }

Rotation History

GET /api/v1/triple-key/rotate/history Free

Retrieve the complete rotation history for a keypair. Returns a chronological list of all rotation events, including the reason, trigger type, and version transitions.

Query Parameters

Parameter Type Required Description
key_id string required The keypair identifier

Example Request

HTTP
GET /api/v1/triple-key/rotate/history?key_id=tk_9f8a7b6c5d4e3f2a1b0c HTTP/1.1 Host: api.h33.ai X-API-Key: h33_pk_your_api_key_here

Response

Field Type Description
key_id string The keypair identifier
current_version integer Current active key version
events array Array of rotation event objects
events[].rotation_id string Unique rotation event identifier
events[].from_version integer Previous key version
events[].to_version integer New key version after rotation
events[].trigger string "manual" | "scheduled" | "policy"
events[].reason string Reason for rotation (if provided)
events[].timestamp string ISO 8601 timestamp of rotation

Example Response

JSON
{ "key_id": "tk_9f8a7b6c5d4e3f2a1b0c", "current_version": 3, "events": [ { "rotation_id": "rot_x1y2z3", "from_version": 1, "to_version": 2, "trigger": "scheduled", "reason": "Auto-rotation (30-day policy)", "timestamp": "2026-01-23T00:00:00Z" }, { "rotation_id": "rot_a1b2c3d4e5f6", "from_version": 2, "to_version": 3, "trigger": "manual", "reason": "Scheduled compliance rotation", "timestamp": "2026-02-22T08:30:00Z" } ] }

Code Examples

Complete working examples for the generate, sign, and verify flow in multiple languages.

curl

Bash
# 1. Generate a keypair KEY_RESPONSE=$(curl -s -X POST https://api.h33.ai/api/v1/triple-key/generate \ -H "Content-Type: application/json" \ -H "X-API-Key: $H33_API_KEY" \ -d '{"label": "demo-key", "security_level": "standard"}') KEY_ID=$(echo $KEY_RESPONSE | jq -r '.key_id') ED25519_PK=$(echo $KEY_RESPONSE | jq -r '.ed25519_public_key') DILITHIUM_PK=$(echo $KEY_RESPONSE | jq -r '.dilithium_public_key') FALCON_PK=$(echo $KEY_RESPONSE | jq -r '.falcon_public_key') echo "Key ID: $KEY_ID" # 2. Sign a message MESSAGE_B64=$(echo -n "Hello, Triple Key!" | base64) SIGN_RESPONSE=$(curl -s -X POST https://api.h33.ai/api/v1/triple-key/sign \ -H "Content-Type: application/json" \ -H "X-API-Key: $H33_API_KEY" \ -d "{\"key_id\": \"$KEY_ID\", \"message_b64\": \"$MESSAGE_B64\"}") SIGNATURE=$(echo $SIGN_RESPONSE | jq -r '.signature_b64') echo "Signature: ${SIGNATURE:0:40}..." # 3. Verify the signature curl -s -X POST https://api.h33.ai/api/v1/triple-key/verify \ -H "Content-Type: application/json" \ -H "X-API-Key: $H33_API_KEY" \ -d "{ \"message_b64\": \"$MESSAGE_B64\", \"signature_b64\": \"$SIGNATURE\", \"ed25519_public_key\": \"$ED25519_PK\", \"dilithium_public_key\": \"$DILITHIUM_PK\", \"falcon_public_key\": \"$FALCON_PK\" }" | jq .

Python

Python
import requests import base64 API_KEY = "h33_pk_your_api_key_here" BASE_URL = "https://api.h33.ai/api/v1/triple-key" HEADERS = { "Content-Type": "application/json", "X-API-Key": API_KEY, } # 1. Generate a keypair gen = requests.post( f"{BASE_URL}/generate", headers=HEADERS, json={"label": "python-demo", "security_level": "high"}, ).json() key_id = gen["key_id"] print(f"Generated key: {key_id}") # 2. Sign a message message = base64.b64encode(b"Hello, Triple Key!").decode() sig = requests.post( f"{BASE_URL}/sign", headers=HEADERS, json={"key_id": key_id, "message_b64": message}, ).json() print(f"Signed with algorithm: {sig['algorithm']}") # 3. Verify the signature verify = requests.post( f"{BASE_URL}/verify", headers=HEADERS, json={ "message_b64": message, "signature_b64": sig["signature_b64"], "ed25519_public_key": gen["ed25519_public_key"], "dilithium_public_key": gen["dilithium_public_key"], "falcon_public_key": gen["falcon_public_key"], }, ).json() print(f"Valid: {verify['valid']}") print(f"Layers verified: {verify['layers_verified']}")

Node.js

JavaScript
const API_KEY = "h33_pk_your_api_key_here"; const BASE = "https://api.h33.ai/api/v1/triple-key"; async function tripleKeyDemo() { const headers = { "Content-Type": "application/json", "X-API-Key": API_KEY, }; // 1. Generate a keypair const gen = await fetch(`${BASE}/generate`, { method: "POST", headers, body: JSON.stringify({ label: "node-demo", security_level: "standard", }), }).then(r => r.json()); console.log("Key ID:", gen.key_id); // 2. Sign a message const messageB64 = Buffer.from("Hello, Triple Key!").toString("base64"); const sig = await fetch(`${BASE}/sign`, { method: "POST", headers, body: JSON.stringify({ key_id: gen.key_id, message_b64: messageB64, }), }).then(r => r.json()); console.log("Algorithm:", sig.algorithm); // 3. Verify the signature const result = await fetch(`${BASE}/verify`, { method: "POST", headers, body: JSON.stringify({ message_b64: messageB64, signature_b64: sig.signature_b64, ed25519_public_key: gen.ed25519_public_key, dilithium_public_key: gen.dilithium_public_key, falcon_public_key: gen.falcon_public_key, }), }).then(r => r.json()); console.log("Valid:", result.valid); console.log("Layers:", result.layers_verified); } tripleKeyDemo();

Rust

Rust
use base64::{engine::general_purpose::STANDARD, Engine}; use reqwest::Client; use serde_json::{json, Value}; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let client = Client::new(); let api_key = "h33_pk_your_api_key_here"; let base = "https://api.h33.ai/api/v1/triple-key"; // 1. Generate a keypair let gen: Value = client .post(format!("{base}/generate")) .header("X-API-Key", api_key) .json(&json!({ "label": "rust-demo", "security_level": "standard" })) .send().await? .json().await?; let key_id = gen["key_id"].as_str().unwrap(); println!("Key ID: {key_id}"); // 2. Sign a message let message_b64 = STANDARD.encode(b"Hello, Triple Key!"); let sig: Value = client .post(format!("{base}/sign")) .header("X-API-Key", api_key) .json(&json!({ "key_id": key_id, "message_b64": message_b64 })) .send().await? .json().await?; println!("Algorithm: {}", sig["algorithm"]); // 3. Verify the signature let result: Value = client .post(format!("{base}/verify")) .header("X-API-Key", api_key) .json(&json!({ "message_b64": message_b64, "signature_b64": sig["signature_b64"], "ed25519_public_key": gen["ed25519_public_key"], "dilithium_public_key": gen["dilithium_public_key"], "falcon_public_key": gen["falcon_public_key"] })) .send().await? .json().await?; println!("Valid: {}", result["valid"]); println!("Layers: {}", result["layers_verified"]); Ok(()) }

FAQ

What does the Triple Key API do?

It generates a linked keypair, signs a message with Ed25519 + Dilithium-5 (ML-DSA-87) + FALCON-512 in one call, and verifies the resulting composite signature. All three layers must verify for the signature to be valid.

What's the minimal call to get started?

POST /api/v1/triple-key/generate with your X-API-Key header returns a keypair; then /sign and /verify use it. The demo key h33_demo_triple_key_public allows 100 operations per day for testing (not for production).

What doesn't it do?

It signs and verifies; it does not encrypt data, does not compute over ciphertext (that's FHE), and does not prove statements without revealing them (that's ZK). It is a multi-algorithm signature API, not a key-management vault.

How is it different from H33-Key?

H33-Key controls how an existing secret is used without exposing its plaintext. Triple Key produces signatures from key material it generates and stores server-side. Use H33-Key to protect a Stripe or cloud key; use Triple Key to sign artifacts with post-quantum durability.

Why three algorithms instead of one?

Defense in depth. Ed25519, Dilithium-5, and FALCON-512 rest on independent hardness assumptions (classical ECC, Module-LWE, and NTRU lattices). A break in one does not compromise the others; a valid composite signature requires all three to pass.

Is FALCON a finalized standard?

FALCON is being standardized as FN-DSA under FIPS 206, which is still in draft. Dilithium-5 corresponds to ML-DSA-87 (FIPS 204). Treat maturity claims as scoped to those standards' status.