oqs 2.4.0
oqs: ^2.4.0 copied to clipboard
Dart FFI bindings for liboqs — high-performance post-quantum cryptography (PQC) with ML-KEM, ML-DSA, Falcon, SPHINCS+ for key encapsulation and signatures.
OQS - Post-Quantum Cryptography for Dart #
Dart bindings for liboqs - quantum-resistant cryptography.
- Key Exchange (KEM): ML-KEM (Kyber), FrodoKEM, Classic McEliece, NTRU Prime
- Digital Signatures: ML-DSA (Dilithium), Falcon, SPHINCS+, MAYO
- Secure Random: Hardware-backed cryptographic RNG
- Cross-Platform: Android, iOS, Linux, macOS, Windows
Quick Start #
1. Add Dependency #
dependencies:
oqs: ^2.4.0
2. Get liboqs Binaries #
Download pre-built binaries from liboqs-binaries releases.
Extract and place files:
# Dart/Flutter project
your_project/
├── bin/
│ ├── oqs.dll # Windows
│ └── linux/liboqs.so # Linux
├── lib/liboqs.dylib # macOS
└── pubspec.yaml
# Flutter Android (jniLibs)
android/app/src/main/jniLibs/
├── arm64-v8a/liboqs.so
├── armeabi-v7a/liboqs.so
└── x86_64/liboqs.so
# Flutter iOS
# Drag liboqs.xcframework into Xcode project
Or configure manually:
import 'package:oqs/oqs.dart';
LibOQSLoader.customPaths = LibraryPaths(
windows: 'C:/libs/oqs.dll',
linux: '/usr/local/lib/liboqs.so',
macOS: '/opt/homebrew/lib/liboqs.dylib',
);
3. Usage #
Key Exchange:
import 'package:oqs/oqs.dart';
void main() {
// Create KEM instance
final kem = KEM.create('ML-KEM-768')!;
// Alice generates keys
final keyPair = kem.generateKeyPair();
// Bob encapsulates
final result = kem.encapsulate(keyPair.publicKey);
// Alice decapsulates
final aliceSecret = kem.decapsulate(result.ciphertext, keyPair.secretKey);
// Secrets match!
print(aliceSecret == result.sharedSecret); // true
kem.dispose();
}
Digital Signatures:
import 'dart:convert';
import 'package:oqs/oqs.dart';
void main() {
final sig = Signature.create('ML-DSA-65');
// Generate keys
final keys = sig.generateKeyPair();
// Sign
final message = utf8.encode('Hello quantum world');
final signature = sig.sign(message, keys.secretKey);
// Verify
final valid = sig.verify(message, signature, keys.publicKey);
print(valid); // true
sig.dispose();
}
Random Generation:
import 'package:oqs/oqs.dart';
void main() {
// Generate random bytes
final bytes = OQSRandom.generateBytes(32);
// Generate seed for key derivation
final seed = OQSRandom.generateSeed();
// Random integers
final dice = OQSRandom.generateInt(1, 7); // 1-6
// Cryptographically shuffle
final deck = [1, 2, 3, 4, 5];
OQSRandomExtensions.shuffleList(deck);
}
API Reference #
KEM (Key Exchange) #
// Create
final kem = KEM.create('ML-KEM-768')!;
// Properties
kem.algorithmName // "ML-KEM-768"
kem.publicKeyLength // 1184
kem.secretKeyLength // 2400
kem.ciphertextLength // 1088
kem.sharedSecretLength // 32
// Operations
final keyPair = kem.generateKeyPair();
final result = kem.encapsulate(publicKey);
final secret = kem.decapsulate(ciphertext, secretKey);
// Cleanup
kem.dispose();
Signature #
// Create
final sig = Signature.create('ML-DSA-65');
// Properties
sig.algorithmName // "ML-DSA-65"
sig.publicKeyLength // 1952
sig.secretKeyLength // 4032
sig.maxSignatureLength // 3309
// Operations
final keyPair = sig.generateKeyPair();
final signature = sig.sign(message, secretKey);
final valid = sig.verify(message, signature, publicKey);
// Cleanup
sig.dispose();
Random #
// Bytes
OQSRandom.generateBytes(32);
OQSRandom.generateSeed();
// Numbers
OQSRandom.generateInt(1, 100);
OQSRandomExtensions.generateBool();
OQSRandomExtensions.generateDouble();
// Utilities
OQSRandomExtensions.shuffleList(myList);
Discovery #
// List supported algorithms
final kems = LibOQS.getSupportedKEMAlgorithms();
final sigs = LibOQS.getSupportedSignatureAlgorithms();
// Check support
LibOQS.isKEMSupported('ML-KEM-768'); // true
LibOQS.isSignatureSupported('ML-DSA-65'); // true
// Version
LibOQS.getVersion(); // "0.15.0"
Algorithms #
Key Exchange (KEM)
NIST Standardized:
ML-KEM-512,ML-KEM-768,ML-KEM-1024⭐ (recommended)
Legacy Names:
Kyber512,Kyber768,Kyber1024
Others:
- Classic McEliece (10 variants)
- FrodoKEM (6 variants)
sntrup761
Digital Signatures
NIST Standardized:
ML-DSA-44,ML-DSA-65,ML-DSA-87⭐ (recommended)
Legacy Names:
Dilithium2,Dilithium3,Dilithium5
Others:
- Falcon (4 variants)
- SPHINCS+ (12 variants)
- MAYO (4 variants)
- Cross-Tree (9 variants)
- SNOVA (14 variants)
- OV (12 variants)
Platform Setup #
Option 1: Pre-built Binaries (Easiest) #
Download from releases and place in your project.
Option 2: System Install #
Ubuntu/Debian:
sudo apt install liboqs-dev
macOS:
brew install liboqs
Windows:
vcpkg install liboqs
Option 3: Build from Source #
git clone https://github.com/open-quantum-safe/liboqs.git
cd liboqs && mkdir build && cd build
cmake -GNinja -DCMAKE_INSTALL_PREFIX=/usr/local ..
ninja install
Advanced #
Library Loading #
The package tries multiple strategies automatically:
- Explicit path (if provided)
- Platform-specific custom paths
- Environment variable (
LIBOQS_PATH) - Project directories (
bin/,lib/) - System locations (
/usr/lib,/usr/local/lib)
Manual configuration:
// Per-platform paths
LibOQSLoader.customPaths = LibraryPaths(
windows: 'C:/libs/oqs.dll',
linux: '/usr/local/lib/liboqs.so',
macOS: '/usr/local/lib/liboqs.dylib',
androidArm64: '/data/app/libs/liboqs.so',
);
// From extracted binary release
LibOQSLoader.customPaths = LibraryPaths.fromBinaryRoot(
'/path/to/liboqs-0.15.0'
);
// Single explicit path
final lib = LibOQSLoader.loadLibrary(
explicitPath: '/custom/path/liboqs.so'
);
Performance #
// Initialize once at app startup
void main() {
LibOQS.init(); // Enables optimizations
runApp(MyApp());
}
// Always dispose when done
final kem = KEM.create('ML-KEM-768')!;
// ... use kem ...
kem.dispose(); // Free resources
Thread Safety #
// Safe: Each thread can use library independently
// Just call LibOQS.init() once globally
// Long-running server cleanup
void shutdown() {
LibOQS.cleanup(); // Clean OpenSSL resources
}
Troubleshooting #
Library not found:
// Set environment variable
export LIBOQS_PATH=/path/to/liboqs.so
// Or configure paths
LibOQSLoader.customPaths = LibraryPaths(
linux: '/usr/local/lib/liboqs.so',
);
Algorithm not supported:
// Check if enabled
if (!LibOQS.isKEMSupported('ML-KEM-768')) {
print('Not available in this build');
}
// List what's available
print(LibOQS.getSupportedKEMAlgorithms());
Invalid key length:
// Get expected sizes first
final kem = KEM.create('ML-KEM-768')!;
print('Public key: ${kem.publicKeyLength}');
print('Secret key: ${kem.secretKeyLength}');
Security Notes #
⚠️ Important:
- Use
ML-KEMandML-DSAfor production (NIST standardized) - Keep liboqs updated
- Always call
dispose()on KEM/Signature instances - Don't share instance objects between threads
- Use
OQSRandom.generateSeed()for key derivation
Examples #
See example/ directory for complete working examples.
Links #
- liboqs - C library
- Open Quantum Safe - Project homepage
- NIST PQC - Standardization