@qpher/sdk
Official Node.js SDK for the Qpher Post-Quantum Cryptography API.
Installation
npm install @qpher/sdkRequirements
- Node.js 18+
Quick Start
Get a free API key (no credit card): https://portal.qpher.ai/register
import { Qpher } from '@qpher/sdk';
// Initialize the client
const client = new Qpher({ apiKey: 'qph_your_api_key' });
// Encrypt data using Kyber768 KEM.
// keyVersion is optional — omit it and the server uses your active key.
const encrypted = await client.kem.encrypt({
plaintext: Buffer.from('Hello, Quantum World!'),
});
console.log('Ciphertext:', encrypted.ciphertext.toString('hex'));
// Decrypt data — decrypt always needs the exact keyVersion that encrypted it.
const decrypted = await client.kem.decrypt({
ciphertext: encrypted.ciphertext,
keyVersion: encrypted.keyVersion,
});
console.log('Plaintext:', decrypted.plaintext.toString());
// Sign a message using Dilithium3 (keyVersion optional — defaults to active key).
const signed = await client.signatures.sign({
message: Buffer.from('Invoice #12345'),
});
console.log('Signature:', signed.signature.toString('hex'));
// Verify a signature
const verified = await client.signatures.verify({
message: Buffer.from('Invoice #12345'),
signature: signed.signature,
keyVersion: signed.keyVersion,
});
console.log('Valid:', verified.valid);API Reference
Client Initialization
import { Qpher } from '@qpher/sdk';
const client = new Qpher({
apiKey: 'qph_your_api_key', // Required
baseUrl: 'https://api.qpher.ai', // Optional, default
timeout: 30000, // Optional, milliseconds
maxRetries: 3, // Optional
});Some operations require MFA step-up re-verification — see https://docs.qpher.ai/security/mfa
KEM Operations (Kyber768)
Encrypt
keyVersion is optional. Omit it and the server encrypts with your tenant's
active key; the resolved version is returned on result.keyVersion.
const result = await client.kem.encrypt({
plaintext: Buffer.from('secret data'),
mode: 'standard', // Optional: 'standard' | 'deterministic'
salt: Buffer.alloc(32), // Required if mode='deterministic'
});
// result.ciphertext: Buffer
// result.keyVersion: number (the server-resolved active version)
// result.algorithm: string ('Kyber768')
// result.requestId: string
// To pin a specific version instead, pass keyVersion explicitly:
const pinned = await client.kem.encrypt({
plaintext: Buffer.from('secret data'),
keyVersion: 5,
});Decrypt
const result = await client.kem.decrypt({
ciphertext: encryptedData,
keyVersion: 1,
});
// result.plaintext: Buffer
// result.keyVersion: number
// result.algorithm: string
// result.requestId: stringSignature Operations (Dilithium3)
Sign
keyVersion is optional. Omit it and the server signs with your tenant's
active key; the resolved version is returned on result.keyVersion.
const result = await client.signatures.sign({
message: Buffer.from('document to sign'),
});
// result.signature: Buffer (3,293 bytes)
// result.keyVersion: number (the server-resolved active version)
// result.algorithm: string ('Dilithium3')
// result.requestId: string
// To pin a specific version instead, pass keyVersion explicitly:
const pinned = await client.signatures.sign({
message: Buffer.from('document to sign'),
keyVersion: 5,
});Verify
const result = await client.signatures.verify({
message: Buffer.from('document to sign'),
signature: signatureBuffer,
keyVersion: 1,
});
// result.valid: boolean
// result.keyVersion: number
// result.algorithm: string
// result.requestId: stringPost-Quantum Hash-Based Signatures (SLH-DSA / FIPS 205)
Qpher implements FIPS 205 algorithms (SLH-DSA, also known as SPHINCS+), NIST-standardised hash-based signatures. SLH-DSA derives its security from cryptographic hash functions only, providing a conservative alternative to lattice-based signatures like ML-DSA (Dilithium3) for long-term archival and high-assurance workloads.
| Algorithm value | NIST Level | Signature size | Use case |
|---|---|---|---|
SLH-DSA-SHA2-128s |
1 | ~7.9 KB | Small signatures; slower signing |
SLH-DSA-SHA2-128f |
1 | ~17 KB | Faster signing for high-throughput |
SLH-DSA-SHA2-192s |
3 | ~16 KB | Recommended for long-term archive (30+ years) |
SLH-DSA-SHA2-256s |
5 | ~29 KB | Highest security; sovereign / compliance use |
Pass the algorithm value through the existing sign / verify API:
const result = await client.signatures.sign({
message: Buffer.from('contract.pdf bytes'),
keyVersion: 1,
algorithm: 'SLH-DSA-SHA2-192s',
});
// result.signature: Buffer (~16 KB for SHA2-192s)
// result.algorithm: string ('SLH-DSA-SHA2-192s')
const verified = await client.signatures.verify({
message: Buffer.from('contract.pdf bytes'),
signature: result.signature,
keyVersion: 1,
algorithm: 'SLH-DSA-SHA2-192s',
});
// verified.valid: booleanPlan gating: SLH-DSA requires Personal+ plan. See https://qpher.ai/pricing.
Feature flag: SLH-DSA is shipped in this SDK release; the backend
launch is gated behind a per-request feature flag (SLH_DSA_ENABLED)
until the public launch date. Customers who pass SLH-DSA values today
get 503 ERR_SIG_022 — this is the expected transitional behaviour.
Key Management
Generate Key
const result = await client.keys.generate({ algorithm: 'Kyber768' });
// result.keyVersion: number
// result.algorithm: string
// result.status: string ('active')
// result.publicKey: Buffer
// result.createdAt: stringRotate Key
const result = await client.keys.rotate({ algorithm: 'Kyber768' });
// result.keyVersion: number (new)
// result.oldKeyVersion: number
// result.algorithm: string
// result.publicKey: BufferGet Active Key
const keyInfo = await client.keys.getActive({ algorithm: 'Kyber768' });
// keyInfo.keyVersion: number
// keyInfo.algorithm: string
// keyInfo.status: string
// keyInfo.publicKey: Buffer
// keyInfo.createdAt: stringList Keys
const result = await client.keys.list({
algorithm: 'Kyber768', // Optional filter
status: 'active', // Optional filter
});
// result.keys: KeyInfo[]
// result.total: numberRetire Key
const result = await client.keys.retire({
algorithm: 'Kyber768',
keyVersion: 1,
});
// result.keyVersion: number
// result.status: string ('retired')Error Handling
import {
Qpher,
QpherError,
AuthenticationError,
ValidationError,
NotFoundError,
RateLimitError,
} from '@qpher/sdk';
try {
const result = await client.kem.encrypt({
plaintext: Buffer.from('data'),
keyVersion: 99,
});
} catch (err) {
if (err instanceof NotFoundError) {
console.log(`Key not found: ${err.message}`);
console.log(`Error code: ${err.errorCode}`);
console.log(`Request ID: ${err.requestId}`);
} else if (err instanceof RateLimitError) {
console.log('Rate limit exceeded, please retry later');
} else if (err instanceof AuthenticationError) {
console.log('Invalid API key');
} else if (err instanceof ValidationError) {
console.log(`Invalid input: ${err.message}`);
} else if (err instanceof QpherError) {
console.log(`API error: ${err.message}`);
}
}Error Types
| Exception | HTTP Status | Description |
|---|---|---|
AuthenticationError |
401 | Invalid or missing API key |
ValidationError |
400 | Invalid request parameters |
ForbiddenError |
403 | Operation not allowed |
NotFoundError |
404 | Resource not found |
RateLimitError |
429 | Rate limit exceeded |
ServerError |
500+ | Server-side errors |
TimeoutError |
504 | Request timed out |
ConnectionError |
503 | Connection failed |
TypeScript Support
This SDK is written in TypeScript and provides full type definitions. All input and output types are exported:
import {
QpherOptions,
EncryptInput,
EncryptResult,
DecryptInput,
DecryptResult,
SignInput,
SignResult,
VerifyInput,
VerifyResult,
KeyInfo,
KeyListResult,
// ... and more
} from '@qpher/sdk';Supported Algorithms
| Algorithm | Type | Security Level |
|---|---|---|
| Kyber768 (ML-KEM-768) | KEM (Encryption) | NIST Level 3 |
| Dilithium3 (ML-DSA-65) | Digital Signatures | NIST Level 3 |
| X-Wing (X25519 + ML-KEM-768) | Hybrid KEM | NIST Level 3 |
| Composite ML-DSA (ECDSA P-256 + ML-DSA-65) | Hybrid Signatures | NIST Level 3 |
Hybrid Mode (Pro/Enterprise plans): Pass
algorithm: 'X-Wing'for hybrid KEM oralgorithm: 'Composite-ML-DSA'for hybrid signatures. Without thealgorithmparameter, PQC-only algorithms are used (backward-compatible).Hybrid mode combines PQC with classical cryptography for defense-in-depth: if a lattice cryptanalysis breakthrough weakens ML-KEM or ML-DSA, the classical component (X25519 / ECDSA) still protects your data.
License
MIT License - see LICENSE for details.
Links
- Qpher Website
- API Documentation
- API Reference
- Code Examples
- GitHub Repository
- FIPS 203 — ML-KEM (Kyber768)
- FIPS 204 — ML-DSA (Dilithium3)
Alternative to: liboqs, AWS KMS PQC, Google Cloud KMS PQC.