m_security 0.1.0
m_security: ^0.1.0 copied to clipboard
A high-performance cryptographic SDK for Flutter powered by native Rust via FFI. Provides authenticated encryption (AES-256-GCM, ChaCha20-Poly1305), modern hashing (BLAKE3, SHA-3, Argon2id), and key d [...]
M-Security #
A native Rust security SDK for Flutter, providing high-performance cryptographic services, secure memory management, and (coming soon) an encrypted virtual file system. All operations run in Rust through Flutter Rust Bridge. No Dart-level crypto, no platform channels.
Built and maintained by the Dev Department of MicroClub, the computer science club at USTHB (University of Science and Technology Houari Boumediene, Algiers).
Features #
| Category | Algorithm | Highlights |
|---|---|---|
| AEAD Encryption | AES-256-GCM | Industry-standard, hardware-accelerated on most CPUs |
| ChaCha20-Poly1305 | Optimized for mobile (no AES hardware needed) | |
| Hashing | BLAKE3 | Ultra-fast, one-shot and streaming |
| SHA-3-256 (Keccak) | NIST-standard, one-shot and streaming | |
| Password Hashing | Argon2id | PHC winner, Mobile and Desktop presets |
| Key Derivation | HKDF-SHA256 | RFC 5869, extract-then-expand with domain separation |
Security by design:
- All key material lives in Rust behind opaque handles; raw keys never cross FFI
- Automatic memory zeroization on drop (
ZeroizeOnDrop) - Nonces generated internally via OS-level CSPRNG (
OsRng) - AEAD tag verification prevents silent decryption of tampered data
panic = "abort"in release profile, preventing undefined behavior from panics crossing FFIclippy::unwrap_used = "deny", ensuring all operations returnResult<T, CryptoError>
Installation #
Add to your pubspec.yaml:
dependencies:
m_security: ^0.1.0
Then run:
flutter pub get
Prerequisites #
M-Security compiles Rust code during the Flutter build. You need:
-
Rust toolchain (stable):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -
Platform-specific tools:
Platform Requirements Android Android NDK (r27c recommended) iOS / macOS Xcode with command line tools Linux clang,cmake,ninja-build,pkg-config,libgtk-3-devWindows Visual Studio Build Tools + LLVM
Rust compilation is handled automatically by Cargokit during flutter build / flutter run.
Getting Started #
Initialize the Rust library once at app startup:
import 'package:m_security/m_security.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await RustLib.init();
runApp(const MyApp());
}
Usage #
All examples below use a single import:
import 'package:m_security/m_security.dart';
AES-256-GCM Encryption #
final aes = AesGcmService();
await aes.initWithRandomKey();
// Encrypt and decrypt raw bytes
final encrypted = await aes.encrypt(plaintext);
final decrypted = await aes.decrypt(encrypted);
// Convenience: encrypt and decrypt UTF-8 strings
final ciphertext = await aes.encryptString('sensitive data');
final original = await aes.decryptString(ciphertext);
ChaCha20-Poly1305 Encryption #
final chacha = Chacha20Service();
await chacha.initWithRandomKey();
// Basic encrypt and decrypt
final encrypted = await chacha.encryptString('sensitive data');
final original = await chacha.decryptString(encrypted);
// With Associated Authenticated Data (AAD)
final ct = await chacha.encryptString('payload', aad: 'metadata');
final pt = await chacha.decryptString(ct, aad: 'metadata');
Both ciphers output nonce || ciphertext || tag. Nonces (12 bytes) are auto-generated and authentication tags (16 bytes) are appended automatically.
Argon2id Password Hashing #
// Hash a password (returns PHC-format string)
final hash = await argon2IdHash(password: 'hunter2');
// Verify a password against a hash
await argon2IdVerify(phcHash: hash, password: 'hunter2');
// Explicit preset selection
final hash = await argon2IdHash(
password: 'hunter2',
preset: Argon2Preset.desktop, // 256 MiB, t=4, p=8
);
The default preset is selected at compile time: Argon2Preset.mobile (64 MiB, t=3, p=4) unless built with -DIS_DESKTOP=true.
HKDF-SHA256 Key Derivation #
// Derive a key from input key material
final key = MHKDF.derive(
ikm: masterKeyBytes,
salt: saltBytes, // optional
info: Uint8List.fromList('encryption-key'.codeUnits),
outputLen: 32,
);
// Domain separation: same master key, different derived keys
final encKey = MHKDF.derive(ikm: master, info: utf8.encode('enc'), outputLen: 32);
final macKey = MHKDF.derive(ikm: master, info: utf8.encode('mac'), outputLen: 32);
// Two-phase: extract PRK, then expand
final prk = MHKDF.extract(ikm: masterKeyBytes, salt: saltBytes);
final derived = await MHKDF.expand(prk: prk, info: infoBytes, outputLen: 32);
Output length must be between 1 and 8160 bytes (RFC 5869 limit for SHA-256: 255 * 32).
BLAKE3 & SHA-3-256 Hashing #
For one-shot and streaming hashing, use the lower-level FFI API directly:
import 'package:m_security/src/rust/api/hashing.dart';
// One-shot hashing (32-byte output)
final blake3Digest = await blake3Hash(data: inputBytes);
final sha3Digest = await sha3Hash(data: inputBytes);
// Streaming: process data in chunks
final hasher = createBlake3(); // or createSha3()
await hasherUpdate(handle: hasher, data: chunk1);
await hasherUpdate(handle: hasher, data: chunk2);
final digest = await hasherFinalize(handle: hasher);
// Reset and reuse
await hasherReset(handle: hasher);
Architecture #
Key design decisions:
- Opaque handles.
CipherHandleandHasherHandleare#[frb(opaque)]. Dart holds a pointer, never raw key bytes. - Trait objects.
Box<dyn Encryption>andBox<dyn Hasher>withSend + Sync + 'staticenable runtime algorithm selection. - SecretBuffer. All key material is wrapped in
SecretBufferwhich derivesZeroizeOnDrop. Memory is zeroed when handles are dropped. - No panics across FFI.
panic = "abort"in release profile. All FFI functions returnResult<T, CryptoError>. - Format headers. Encrypted data includes a
MSECmagic header with version and algorithm identifiers for forward compatibility.
Rust API Reference #
Encryption (CipherHandle) #
create_aes256_gcm(key: Vec<u8>) -> Result<CipherHandle>
create_chacha20_poly1305(key: Vec<u8>) -> Result<CipherHandle>
encrypt(cipher, plaintext, aad) -> Result<Vec<u8>>
decrypt(cipher, ciphertext, aad) -> Result<Vec<u8>>
generate_aes256_gcm_key() -> Result<Vec<u8>>
generate_chacha20_poly1305_key() -> Result<Vec<u8>>
encryption_algorithm_id(cipher) -> String
Hashing (HasherHandle) #
blake3_hash(data) -> Vec<u8> (one-shot, 32 bytes)
sha3_hash(data) -> Vec<u8> (one-shot, 32 bytes)
create_blake3() -> HasherHandle (streaming)
create_sha3() -> HasherHandle (streaming)
hasher_update(handle, data) -> Result<()>
hasher_reset(handle) -> Result<()>
hasher_finalize(handle) -> Result<Vec<u8>>
hasher_algorithm_id(handle) -> Result<String>
Password Hashing (Argon2id) #
argon2id_hash(password, preset) -> Result<String> (PHC)
argon2id_hash_with_salt(password, salt, preset) -> Result<String> (PHC)
argon2id_verify(phc_hash, password) -> Result<()>
Presets: Mobile (64 MiB, t=3, p=4) | Desktop (256 MiB, t=4, p=8)
Key Derivation (HKDF-SHA256) #
hkdf_derive(ikm, salt?, info, output_len) -> Result<Vec<u8>> (one-shot)
hkdf_extract(ikm, salt?) -> Result<Vec<u8>> (PRK)
hkdf_expand(prk, info, output_len) -> Result<Vec<u8>>
Platform Support #
| Platform | Target | Status |
|---|---|---|
| Android | aarch64-linux-android, armv7-linux-androideabi |
CI-tested |
| iOS | aarch64-apple-ios, aarch64-apple-ios-sim |
CI-tested |
| macOS | aarch64-apple-darwin, x86_64-apple-darwin |
Supported |
| Linux | x86_64-unknown-linux-gnu |
CI-tested |
| Windows | x86_64-pc-windows-msvc |
Supported |
Testing #
Rust unit tests (79 tests including NIST/RFC test vectors):
cd rust && cargo test
Dart integration tests (44 tests across all features, requires a running device/simulator):
cd example
flutter test integration_test/aes_gcm_test.dart
flutter test integration_test/chacha20_test.dart
flutter test integration_test/hashing_test.dart
flutter test integration_test/argon2_test.dart
flutter test integration_test/hkdf_test.dart
Tech Stack #
| Component | Version |
|---|---|
| Rust | stable |
| Flutter Rust Bridge | 2.11.1 |
| Dart SDK | ^3.10.8 |
| Flutter SDK | >=3.3.0 |
Rust crates: aes-gcm 0.10, chacha20poly1305 0.10, blake3 1.8, sha3 0.10, argon2 0.5, hkdf 0.12, zeroize 1.8
Roadmap #
v0.1.0 ships the cryptographic foundation. The following features are planned for future releases:
| Feature | Description | Status |
|---|---|---|
| Zero-copy stream processing | Process large files (2 GB+) in 64 KB chunks via Rust pointers, keeping RAM usage constant regardless of file size | Planned |
| Compression + encryption pipeline | Raw Data -> Zstd/Brotli -> AES-GCM/ChaCha20. Reduces disk usage and increases entropy before encryption |
Planned |
| Encrypted Virtual File System (EVFS) | Single .vault container with random-access decryption of individual segments, isolated from filesystem exploration |
Planned |
| Secure shredding | Multi-pass overwrite (random noise patterns) before deleting file pointers, preventing forensic recovery | Planned |
| Stealth storage | Ephemeral secrets (API tokens) held in Rust-managed memory with derived-path obfuscation to resist memory dump extraction | Planned |
| Hardware key wrap | Master key generated in Rust, wrap key stored in Secure Enclave (iOS) / KeyStore (Android), unlocked via biometric authentication | Planned |
Contributing #
See CONTRIBUTING.md for development setup, coding standards, and PR workflow.
License #
MIT. See LICENSE for details.
Copyright (c) 2025 MicroClub-USTHB