236 lines
7.5 KiB
Dart
236 lines
7.5 KiB
Dart
/// Primary entry point for CCC cryptographic operations.
|
|
///
|
|
/// All methods delegate to the Rust bridge via `flutter_rust_bridge`.
|
|
/// No cryptographic logic exists in Dart.
|
|
///
|
|
/// Usage:
|
|
/// ```dart
|
|
/// await CccCrypto.init();
|
|
/// final ct = await CccCrypto.encryptAead(
|
|
/// algorithm: CccAeadAlgorithm.aesGcm256,
|
|
/// key: key,
|
|
/// nonce: nonce,
|
|
/// plaintext: data,
|
|
/// aad: Uint8List(0),
|
|
/// );
|
|
/// ```
|
|
library;
|
|
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:ccc_cryptography/ccc_exceptions.dart';
|
|
import 'package:ccc_cryptography/ccc_provider_catalog.dart';
|
|
import 'package:ccc_cryptography/ccc_self_test.dart';
|
|
import 'package:ccc_cryptography/src/rust/api/crypto.dart' as bridge;
|
|
import 'package:ccc_cryptography/src/rust/api/dto.dart';
|
|
import 'package:ccc_cryptography/src/rust/frb_generated.dart';
|
|
|
|
/// Static façade for all CCC cryptographic operations.
|
|
///
|
|
/// Call [init] once at application startup before using any other method.
|
|
abstract final class CccCrypto {
|
|
/// Initialise the FRB runtime and register the wolfSSL provider.
|
|
///
|
|
/// Must be called once before any other [CccCrypto] method.
|
|
/// Safe to call multiple times (idempotent).
|
|
static Future<void> init() async {
|
|
await RustLib.init();
|
|
await bridge.cccInit();
|
|
}
|
|
|
|
// ── Provider info ────────────────────────────────────────────────────────
|
|
|
|
/// Return the names of all registered crypto providers.
|
|
static List<String> listProviders() => bridge.cccListProviders();
|
|
|
|
/// Return the capability catalog for the default provider.
|
|
static Future<CccProviderCatalog> getCapabilities() async {
|
|
try {
|
|
final caps = await bridge.cccCapabilities();
|
|
return CccProviderCatalog.fromCapabilities(caps);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
// ── AEAD ─────────────────────────────────────────────────────────────────
|
|
|
|
/// Encrypt [plaintext] with an AEAD algorithm.
|
|
///
|
|
/// Returns ciphertext with appended authentication tag.
|
|
static Future<Uint8List> encryptAead({
|
|
required CccAeadAlgorithm algorithm,
|
|
required Uint8List key,
|
|
required Uint8List nonce,
|
|
required Uint8List plaintext,
|
|
Uint8List? aad,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccAeadEncrypt(
|
|
algorithm: algorithm,
|
|
key: key,
|
|
nonce: nonce,
|
|
plaintext: plaintext,
|
|
aad: aad ?? Uint8List(0),
|
|
);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
/// Decrypt [ciphertext] (with appended tag) using an AEAD algorithm.
|
|
///
|
|
/// Throws [CccAuthenticationFailed] if the tag does not verify.
|
|
static Future<Uint8List> decryptAead({
|
|
required CccAeadAlgorithm algorithm,
|
|
required Uint8List key,
|
|
required Uint8List nonce,
|
|
required Uint8List ciphertext,
|
|
Uint8List? aad,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccAeadDecrypt(
|
|
algorithm: algorithm,
|
|
key: key,
|
|
nonce: nonce,
|
|
ciphertext: ciphertext,
|
|
aad: aad ?? Uint8List(0),
|
|
);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
// ── KDF ──────────────────────────────────────────────────────────────────
|
|
|
|
/// Derive key material of [length] bytes.
|
|
static Future<Uint8List> deriveKey({
|
|
required CccKdfAlgorithm algorithm,
|
|
required Uint8List ikm,
|
|
Uint8List? salt,
|
|
Uint8List? info,
|
|
required int length,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccKdfDerive(
|
|
algorithm: algorithm,
|
|
ikm: ikm,
|
|
salt: salt ?? Uint8List(0),
|
|
info: info ?? Uint8List(0),
|
|
length: length,
|
|
);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
// ── MAC ──────────────────────────────────────────────────────────────────
|
|
|
|
/// Compute a MAC tag over [data].
|
|
static Future<Uint8List> computeMac({
|
|
required CccMacAlgorithm algorithm,
|
|
required Uint8List key,
|
|
required Uint8List data,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccMacCompute(
|
|
algorithm: algorithm,
|
|
key: key,
|
|
data: data,
|
|
);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
/// Verify a MAC tag. Returns `true` if valid, `false` otherwise.
|
|
static Future<bool> verifyMac({
|
|
required CccMacAlgorithm algorithm,
|
|
required Uint8List key,
|
|
required Uint8List data,
|
|
required Uint8List mac,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccMacVerify(
|
|
algorithm: algorithm,
|
|
key: key,
|
|
data: data,
|
|
mac: mac,
|
|
);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
// ── Hash ─────────────────────────────────────────────────────────────────
|
|
|
|
/// Compute a cryptographic hash of [data].
|
|
static Future<Uint8List> hash({
|
|
required CccHashAlgorithm algorithm,
|
|
required Uint8List data,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccHash(algorithm: algorithm, data: data);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
// ── KEM ──────────────────────────────────────────────────────────────────
|
|
|
|
/// Generate a KEM key pair.
|
|
static Future<CccKemKeyPair> kemGenerateKeypair({
|
|
required CccKemAlgorithm algorithm,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccKemGenerateKeypair(algorithm: algorithm);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
/// KEM encapsulation — produce ciphertext + shared secret from a public key.
|
|
static Future<CccKemEncapResult> kemEncapsulate({
|
|
required CccKemAlgorithm algorithm,
|
|
required Uint8List publicKey,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccKemEncapsulate(
|
|
algorithm: algorithm,
|
|
publicKey: publicKey,
|
|
);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
/// KEM decapsulation — recover shared secret from ciphertext + private key.
|
|
static Future<Uint8List> kemDecapsulate({
|
|
required CccKemAlgorithm algorithm,
|
|
required Uint8List privateKey,
|
|
required Uint8List ciphertext,
|
|
}) async {
|
|
try {
|
|
return await bridge.cccKemDecapsulate(
|
|
algorithm: algorithm,
|
|
privateKey: privateKey,
|
|
ciphertext: ciphertext,
|
|
);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
|
|
// ── Self-test ────────────────────────────────────────────────────────────
|
|
|
|
/// Run the provider self-test suite and return a structured report.
|
|
static Future<CccSelfTestResult> runSelfTest() async {
|
|
try {
|
|
final report = await bridge.cccSelfTest();
|
|
return CccSelfTestResult.fromReport(report);
|
|
} on CccCryptoError catch (e) {
|
|
throw CccException.from(e);
|
|
}
|
|
}
|
|
}
|