flutter_ever_crypto 0.1.1
flutter_ever_crypto: ^0.1.1 copied to clipboard
Flutter plugin for Ever Crypto - XChaCha20Poly1305 and Kyber1024 post-quantum cryptography
Flutter Ever Crypto #
A Flutter plugin that provides easy-to-use APIs for modern cryptographic operations using the ever-crypto Rust library.
Features #
- 🔒 XChaCha20Poly1305: Fast, secure authenticated encryption with extended nonce
- 🛡️ Kyber1024: Post-quantum key encapsulation mechanism
- 🚀 Simple API: Easy to use, hard to misuse
- 🔐 Memory Safety: Automatic secure memory cleanup
- ✅ Cross Platform: Works on Android, iOS, Linux, macOS, and Windows
- 🌊 Flutter Integration: Native Dart types and error handling
Cryptographic Primitives #
XChaCha20Poly1305 #
- Key Size: 256 bits (32 bytes)
- Nonce Size: 192 bits (24 bytes) - extended nonce prevents reuse
- Authentication: Built-in authentication prevents tampering
- Performance: Optimized for both software and hardware implementations
Kyber1024 #
- Security Level: NIST Level 5 (highest security)
- Public Key: 1,568 bytes
- Secret Key: 3,168 bytes
- Ciphertext: 1,568 bytes
- Shared Secret: 32 bytes
- Quantum Resistance: Secure against both classical and quantum attacks
Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
flutter_ever_crypto: ^0.1.0
Then run:
flutter pub get
Requirements #
- Flutter 3.3.0 or later
- Dart 3.8.1 or later
- Rust toolchain (for building from source)
Platform-specific Requirements #
Android: NDK r21 or later iOS: Xcode 12 or later Linux: GCC or Clang macOS: Xcode 12 or later Windows: Visual Studio 2019 or later
Quick Start #
import 'package:flutter_ever_crypto/flutter_ever_crypto.dart';
import 'dart:convert';
import 'dart:typed_data';
// XChaCha20Poly1305 Encryption
void encryptExample() {
// Generate key and nonce
final key = EverCrypto.generateXChaChaKey();
final nonce = EverCrypto.generateXChaChaNonce();
// Encrypt message
final message = 'Hello, World!';
final plaintext = Uint8List.fromList(utf8.encode(message));
final ciphertext = EverCrypto.xchachaEncrypt(key, nonce, plaintext);
// Decrypt message
final decrypted = EverCrypto.xchachaDecrypt(key, nonce, ciphertext);
final decryptedMessage = utf8.decode(decrypted);
print('Original: $message');
print('Decrypted: $decryptedMessage');
}
// Kyber1024 Key Exchange
void keyExchangeExample() {
// Alice generates a key pair
final aliceKeyPair = EverCrypto.generateKyberKeyPair();
// Bob encapsulates a shared secret for Alice
final bobResult = EverCrypto.kyberEncapsulate(aliceKeyPair.publicKey);
// Alice decapsulates the shared secret
final aliceSharedSecret = EverCrypto.kyberDecapsulate(
bobResult.ciphertext,
aliceKeyPair.secretKey,
);
// Both parties now have the same shared secret
print('Shared secrets match: ${bobResult.sharedSecret == aliceSharedSecret}');
}
API Reference #
EverCrypto Class #
Static Methods
XChaCha20Poly1305 Operations
static Uint8List generateXChaChaKey()
- Generate a random 32-byte keystatic Uint8List generateXChaChaNonce()
- Generate a random 24-byte noncestatic Uint8List xchachaEncrypt(Uint8List key, Uint8List nonce, Uint8List plaintext, {Uint8List? aad})
- Encrypt datastatic Uint8List xchachaDecrypt(Uint8List key, Uint8List nonce, Uint8List ciphertext, {Uint8List? aad})
- Decrypt data
Kyber1024 Operations
static KyberKeyPair generateKyberKeyPair()
- Generate a new key pairstatic KyberEncapsulateResult kyberEncapsulate(Uint8List publicKey)
- Encapsulate shared secretstatic Uint8List kyberDecapsulate(Uint8List ciphertext, Uint8List secretKey)
- Decapsulate shared secret
Data Classes #
KyberKeyPair
class KyberKeyPair {
final Uint8List publicKey; // 1,568 bytes
final Uint8List secretKey; // 3,168 bytes
}
KyberEncapsulateResult
class KyberEncapsulateResult {
final Uint8List sharedSecret; // 32 bytes
final Uint8List ciphertext; // 1,568 bytes
}
Exception Handling #
The plugin throws EverCryptoException
for all cryptographic errors:
try {
final result = EverCrypto.xchachaEncrypt(key, nonce, plaintext);
} catch (e) {
if (e is EverCryptoException) {
print('Crypto error: ${e.message}');
print('Error type: ${e.error}');
}
}
Usage Examples #
Secure Messaging #
class SecureMessaging {
static String encryptMessage(String message, Uint8List key) {
final nonce = EverCrypto.generateXChaChaNonce();
final plaintext = Uint8List.fromList(utf8.encode(message));
final ciphertext = EverCrypto.xchachaEncrypt(key, nonce, plaintext);
// Combine nonce and ciphertext for transmission
final combined = Uint8List(nonce.length + ciphertext.length);
combined.setRange(0, nonce.length, nonce);
combined.setRange(nonce.length, combined.length, ciphertext);
return base64.encode(combined);
}
static String decryptMessage(String encryptedMessage, Uint8List key) {
final combined = base64.decode(encryptedMessage);
final nonce = combined.sublist(0, 24);
final ciphertext = combined.sublist(24);
final decrypted = EverCrypto.xchachaDecrypt(key, nonce, ciphertext);
return utf8.decode(decrypted);
}
}
Post-Quantum Key Exchange #
class PostQuantumKeyExchange {
static Future<Uint8List> performKeyExchange(
Uint8List remotePublicKey,
) async {
// Encapsulate a shared secret with the remote party's public key
final result = EverCrypto.kyberEncapsulate(remotePublicKey);
// Send result.ciphertext to the remote party
// The remote party will decapsulate with their secret key
// Both parties will have result.sharedSecret
return result.sharedSecret;
}
static Uint8List completeKeyExchange(
Uint8List ciphertext,
Uint8List secretKey,
) {
// Decapsulate the shared secret from the received ciphertext
return EverCrypto.kyberDecapsulate(ciphertext, secretKey);
}
}
Hybrid Encryption (Recommended) #
class HybridEncryption {
static Map<String, String> encrypt(String message, Uint8List publicKey) {
// Step 1: Key encapsulation with Kyber1024
final kemResult = EverCrypto.kyberEncapsulate(publicKey);
// Step 2: Use shared secret as XChaCha20Poly1305 key
final xchachaKey = kemResult.sharedSecret;
final nonce = EverCrypto.generateXChaChaNonce();
// Step 3: Encrypt message with XChaCha20Poly1305
final plaintext = Uint8List.fromList(utf8.encode(message));
final ciphertext = EverCrypto.xchachaEncrypt(xchachaKey, nonce, plaintext);
return {
'kemCiphertext': base64.encode(kemResult.ciphertext),
'nonce': base64.encode(nonce),
'ciphertext': base64.encode(ciphertext),
};
}
static String decrypt(
Map<String, String> encryptedData,
Uint8List secretKey,
) {
// Step 1: Decapsulate shared secret
final kemCiphertext = base64.decode(encryptedData['kemCiphertext']!);
final sharedSecret = EverCrypto.kyberDecapsulate(kemCiphertext, secretKey);
// Step 2: Decrypt message with XChaCha20Poly1305
final nonce = base64.decode(encryptedData['nonce']!);
final ciphertext = base64.decode(encryptedData['ciphertext']!);
final decrypted = EverCrypto.xchachaDecrypt(sharedSecret, nonce, ciphertext);
return utf8.decode(decrypted);
}
}
Security Considerations #
Key Management #
- Never hardcode keys in your application
- Generate keys securely using the provided functions
- Store keys securely using Flutter Secure Storage or similar
- Rotate keys regularly for long-term applications
Nonce Management #
- Never reuse nonces with the same key
- Generate nonces randomly for each encryption
- Include nonces with transmitted ciphertext
General Security #
- Validate inputs before cryptographic operations
- Handle errors securely - don't leak information
- Use hybrid encryption for maximum security
- Keep dependencies updated for security patches
Performance #
Benchmarks (MacBook Pro M1) #
Operation | Performance |
---|---|
XChaCha20Poly1305 Encryption | ~7 MB/s |
XChaCha20Poly1305 Decryption | ~7 MB/s |
Kyber1024 Key Generation | ~0.4 ms |
Kyber1024 Encapsulation | ~0.46 ms |
Kyber1024 Decapsulation | ~0.41 ms |
Performance may vary based on device capabilities and message size.
Troubleshooting #
Build Issues #
Error: Rust toolchain not found
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
Error: Android NDK not found
# Install Android NDK via Android Studio
# Or set ANDROID_NDK_ROOT environment variable
Error: Library not found at runtime
- Ensure the native library is properly bundled
- Check platform-specific build configurations
- Verify target architecture matches device
Runtime Errors #
EverCryptoException: Invalid key length
- Ensure keys are exactly 32 bytes for XChaCha20Poly1305
- Use
generateXChaChaKey()
for proper key generation
EverCryptoException: Decryption failed
- Verify the key and nonce are correct
- Check that ciphertext hasn't been corrupted
- Ensure AAD (if used) matches encryption
Contributing #
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments #
- Built on the ever-crypto Rust library
- Uses chacha20poly1305 for authenticated encryption
- Uses pqcrypto-kyber for post-quantum cryptography
Support #
For bug reports and feature requests, please use the GitHub Issues page.