@qsegroup/qrek
v0.0.3
Published
qREK Node.js SDK - Quantum-Resilient Encryption Kit
Maintainers
Readme
qREK Node.js SDK
Node.js bindings for qREK - Quantum-Resilient Encryption Kit.
Generate cryptographic keys using real quantum entropy from the QSE API.
Installation
npm install @qsegroup/qrekQuick Start
const { QrekNodeClient } = require('@qsegroup/qrek');
// Set your API token
process.env.QREK_API_TOKEN = 'your-qse-api-token';
// Initialize client
const client = new QrekNodeClient();
// Generate AES-256 key with quantum entropy
const aes = await client.generateAesKey();
console.log('Key:', aes.key_base64);
console.log('Entropy ID:', aes.entropy_id);Features
- AES-256 Key Generation - Quantum-entropy-seeded symmetric keys
- RSA Keypair Generation - 2048/3072/4096-bit keypairs
- File Encryption/Decryption - XChaCha20-Poly1305 authenticated encryption
- Stream Encryption - Chunked encryption for large files
- Container Inspection - View metadata without decryption key
- Ed25519 Signatures - Sign and verify container headers
- Hybrid Encryption - RSA-OAEP key wrapping
- Full Provenance - Track WHO/WHEN/WHY/ENTROPY_ID
- Native Performance - Built with Rust via napi-rs
API Reference
Initialize Client
const { QrekNodeClient } = require('@qsegroup/qrek');
// Option 1: Use QREK_API_TOKEN environment variable
const client = new QrekNodeClient();
// Option 2: Pass token directly
const client = new QrekNodeClient('your-qse-api-token');Generate AES-256 Key
const result = await client.generateAesKey();
console.log(result.key_base64); // Base64-encoded 256-bit key
console.log(result.key_hex); // Hex-encoded key
console.log(result.entropy_id); // QSE entropy identifier
console.log(result.signature_verified); // true if QSE signature validGenerate RSA Keypair
// Supported sizes: 2048, 3072, 4096
const result = await client.generateRsaKeypair(2048);
console.log(result.private_key_pem); // PKCS#8 PEM format
console.log(result.public_key_pem); // Public key PEM
console.log(result.public_key_openssh); // OpenSSH format
console.log(result.entropy_id); // QSE entropy identifier
console.log(result.signature_verified); // true if QSE signature validEncrypt File
Encrypt a file with XChaCha20-Poly1305 authenticated encryption.
// First generate a key
const key = await client.generateAesKey();
// Encrypt file
const result = await client.encryptFile(
'secret.txt', // Input file path
'secret.qrek', // Output file path
key.key_base64, // Encryption key
'[email protected]', // Optional: who encrypted
'Secure backup' // Optional: why encrypted
);
console.log(result.output_path); // Path to encrypted file
console.log(result.bytes_encrypted); // Number of bytes encrypted
console.log(result.entropy_id); // Entropy used for this operationDecrypt File
const result = await client.decryptFile(
'secret.qrek', // Input encrypted file
'secret_decrypted.txt', // Output decrypted file
key.key_base64 // Decryption key
);
console.log(result.output_path); // Path to decrypted file
console.log(result.bytes_decrypted); // Number of bytes decryptedInspect Container (Without Decryption Key)
View encrypted file metadata without needing the decryption key - perfect for auditing and compliance.
const info = client.inspectContainer('secret.qrek');
console.log(info.magic); // "qREKv1" - file format
console.log(info.algorithm); // "XChaCha20-Poly1305"
console.log(info.creator); // Who encrypted the file
console.log(info.purpose); // Why it was encrypted
console.log(info.created_at); // When it was encrypted
console.log(info.entropy_id); // QSE entropy ID used
console.log(info.key_provenance_valid); // true if provenance is validUse Case: Compliance Auditing
// Auditor can verify encryption metadata without accessing the data
const info = client.inspectContainer('confidential.qrek');
if (info.key_provenance_valid) {
console.log(`✓ File encrypted by: ${info.creator}`);
console.log(`✓ Encrypted on: ${info.created_at}`);
console.log(`✓ Quantum entropy: ${info.entropy_id}`);
console.log(`✓ Algorithm: ${info.algorithm}`);
} else {
console.log('⚠ Warning: Key provenance could not be verified');
}Stream Encryption (Large Files)
For files too large to fit in memory:
// Encrypt large file in chunks
const result = await client.encryptStream(
'large_video.mp4', // Input file
'large_video.qrek', // Output file
key.key_base64, // Encryption key
65536, // Chunk size (64KB default)
'backup-service', // Optional: creator
'Video archive' // Optional: purpose
);
console.log(result.bytes_encrypted);
console.log(result.chunks_processed);
// Decrypt
const decrypted = await client.decryptStream(
'large_video.qrek',
'large_video_restored.mp4',
key.key_base64
);In-Memory Encryption
Encrypt data without writing to disk:
const plaintext = Buffer.from('Sensitive data to encrypt');
// Encrypt
const encrypted = client.aesEncrypt(Array.from(plaintext), key.key_base64);
const { ciphertext, nonce, tag } = encrypted;
// Decrypt
const decrypted = client.aesDecrypt(ciphertext, nonce, tag, key.key_base64);
const original = Buffer.from(decrypted);Hybrid Encryption (RSA-OAEP)
Wrap symmetric keys with RSA for secure key exchange:
// Generate RSA keypair
const rsa = await client.generateRsaKeypair(2048);
// Generate symmetric key
const symKey = await client.generateAesKey();
// Encrypt symmetric key with RSA public key
const encryptedKey = client.encryptKeyRsaOaep(
symKey.key_base64,
rsa.public_key_pem
);
// Decrypt symmetric key with RSA private key
const decryptedKey = client.decryptKeyRsaOaep(
encryptedKey,
rsa.private_key_pem
);Ed25519 Header Signing (v0.0.3+)
Sign and verify container headers for tamper detection:
// Generate Ed25519 keypair
const keys = client.generateEd25519Keypair();
const { signing_key_hex, verifying_key_hex } = keys;
// Sign container header
const signature = client.signContainerHeader('file.qrek', signing_key_hex);
console.log(signature.signature_base64);
console.log(signature.algorithm); // "Ed25519"
// Verify header
const result = client.verifyContainerHeader('file.qrek', verifying_key_hex);
console.log(result.verified);
console.log(result.has_signature);Complete Example
const { QrekNodeClient } = require('@qsegroup/qrek');
const fs = require('fs');
async function main() {
// Setup
process.env.QREK_API_TOKEN = 'your-qse-api-token';
const client = new QrekNodeClient();
// 1. Generate encryption key
const key = await client.generateAesKey();
console.log(`Generated key with entropy: ${key.entropy_id}`);
// 2. Encrypt a file
await client.encryptFile(
'confidential.pdf',
'confidential.qrek',
key.key_base64,
'[email protected]',
'HR confidential document'
);
console.log('File encrypted successfully');
// 3. Inspect without decryption (for auditing)
const info = client.inspectContainer('confidential.qrek');
console.log(`Encrypted by: ${info.creator}`);
console.log(`Created at: ${info.created_at}`);
console.log(`Quantum verified: ${info.key_provenance_valid}`);
// 4. Decrypt when needed
await client.decryptFile(
'confidential.qrek',
'confidential_restored.pdf',
key.key_base64
);
console.log('File decrypted successfully');
}
main().catch(console.error);ES Modules
import { QrekNodeClient } from '@qsegroup/qrek';
const client = new QrekNodeClient();
const key = await client.generateAesKey();Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| QREK_API_TOKEN | Your QSE API token | Yes |
| QREK_API_URL | Custom API endpoint | No |
Error Handling
try {
const result = await client.generateAesKey();
} catch (error) {
console.error('Error:', error.message);
}TypeScript Support
TypeScript definitions are included:
import { QrekNodeClient } from '@qsegroup/qrek';
const client = new QrekNodeClient();
const result: { key_base64: string; entropy_id: string } = await client.generateAesKey();License
MIT OR Apache-2.0
Links
- Repository: https://github.com/qsegroup/qREK
- Documentation: https://github.com/qsegroup/qREK/tree/main/docs
- Issues: https://github.com/qsegroup/qREK/issues
