npm package: @qpher/sdk
Description: Official Node.js SDK for the Qpher Post-Quantum Cryptography API — ML-KEM-768 (FIPS 203) encryption and ML-DSA-65 (FIPS 204) digital signatures. Alternative to liboqs.
Author: Qpher
Latest version: 0.3.1

# @qpher/sdk

Official Node.js SDK for the [Qpher](https://qpher.ai) Post-Quantum Cryptography API.

## Installation

```bash
npm install @qpher/sdk
```

## Requirements

- Node.js 18+

## Quick Start

```typescript
import { Qpher } from '@qpher/sdk';

// Initialize the client
const client = new Qpher({ apiKey: 'qph_live_your_api_key' });

// Encrypt data using Kyber768 KEM
const encrypted = await client.kem.encrypt({
  plaintext: Buffer.from('Hello, Quantum World!'),
  keyVersion: 1,
});
console.log('Ciphertext:', encrypted.ciphertext.toString('hex'));

// Decrypt data
const decrypted = await client.kem.decrypt({
  ciphertext: encrypted.ciphertext,
  keyVersion: encrypted.keyVersion,
});
console.log('Plaintext:', decrypted.plaintext.toString());

// Sign a message using Dilithium3
const signed = await client.signatures.sign({
  message: Buffer.from('Invoice #12345'),
  keyVersion: 1,
});
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

```typescript
import { Qpher } from '@qpher/sdk';

const client = new Qpher({
  apiKey: 'qph_live_your_api_key', // Required
  baseUrl: 'https://api.qpher.ai', // Optional, default
  timeout: 30000,                   // Optional, milliseconds
  maxRetries: 3,                    // Optional
});
```

### KEM Operations (Kyber768)

#### Encrypt

```typescript
const result = await client.kem.encrypt({
  plaintext: Buffer.from('secret data'),
  keyVersion: 1,
  mode: 'standard',           // Optional: 'standard' | 'deterministic'
  salt: Buffer.alloc(32),     // Required if mode='deterministic'
});
// result.ciphertext: Buffer
// result.keyVersion: number
// result.algorithm: string ('Kyber768')
// result.requestId: string
```

#### Decrypt

```typescript
const result = await client.kem.decrypt({
  ciphertext: encryptedData,
  keyVersion: 1,
});
// result.plaintext: Buffer
// result.keyVersion: number
// result.algorithm: string
// result.requestId: string
```

### Signature Operations (Dilithium3)

#### Sign

```typescript
const result = await client.signatures.sign({
  message: Buffer.from('document to sign'),
  keyVersion: 1,
});
// result.signature: Buffer (3,293 bytes)
// result.keyVersion: number
// result.algorithm: string ('Dilithium3')
// result.requestId: string
```

#### Verify

```typescript
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: string
```

### Key Management

#### Generate Key

```typescript
const result = await client.keys.generate({ algorithm: 'Kyber768' });
// result.keyVersion: number
// result.algorithm: string
// result.status: string ('active')
// result.publicKey: Buffer
// result.createdAt: string
```

#### Rotate Key

```typescript
const result = await client.keys.rotate({ algorithm: 'Kyber768' });
// result.keyVersion: number (new)
// result.oldKeyVersion: number
// result.algorithm: string
// result.publicKey: Buffer
```

#### Get Active Key

```typescript
const keyInfo = await client.keys.getActive({ algorithm: 'Kyber768' });
// keyInfo.keyVersion: number
// keyInfo.algorithm: string
// keyInfo.status: string
// keyInfo.publicKey: Buffer
// keyInfo.createdAt: string
```

#### List Keys

```typescript
const result = await client.keys.list({
  algorithm: 'Kyber768', // Optional filter
  status: 'active',       // Optional filter
});
// result.keys: KeyInfo[]
// result.total: number
```

#### Retire Key

```typescript
const result = await client.keys.retire({
  algorithm: 'Kyber768',
  keyVersion: 1,
});
// result.keyVersion: number
// result.status: string ('retired')
```

## Error Handling

```typescript
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:

```typescript
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 or `algorithm: 'Composite-ML-DSA'` for hybrid signatures. Without the `algorithm` parameter, 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](LICENSE) for details.

## Links

- [Qpher Website](https://qpher.ai)
- [API Documentation](https://docs.qpher.ai)
- [API Reference](https://docs.qpher.ai/api-reference)
- [Code Examples](https://github.com/qpher/qpher-node/tree/main/examples)
- [GitHub Repository](https://github.com/qpher/qpher-node)
- [FIPS 203 — ML-KEM (Kyber768)](https://csrc.nist.gov/pubs/fips/203/final)
- [FIPS 204 — ML-DSA (Dilithium3)](https://csrc.nist.gov/pubs/fips/204/final)

**Alternative to:** liboqs, AWS KMS PQC, Google Cloud KMS PQC.