diff --git a/veilid-core/src/crypto/byte_array_types.rs b/veilid-core/src/crypto/byte_array_types.rs index 7922d32b..d17acb04 100644 --- a/veilid-core/src/crypto/byte_array_types.rs +++ b/veilid-core/src/crypto/byte_array_types.rs @@ -9,18 +9,24 @@ use data_encoding::BASE64URL_NOPAD; ////////////////////////////////////////////////////////////////////// -/// Length of a public key in bytes +/// Length of a crypto key in bytes #[allow(dead_code)] -pub const PUBLIC_KEY_LENGTH: usize = 32; -/// Length of a public key in bytes after encoding to base64url +pub const CRYPTO_KEY_LENGTH: usize = 32; +/// Length of a crypto key in bytes after encoding to base64url #[allow(dead_code)] -pub const PUBLIC_KEY_LENGTH_ENCODED: usize = 43; +pub const CRYPTO_KEY_LENGTH_ENCODED: usize = 43; +/// Length of a crypto key in bytes +#[allow(dead_code)] +pub const PUBLIC_KEY_LENGTH: usize = CRYPTO_KEY_LENGTH; +/// Length of a crypto key in bytes after encoding to base64url +#[allow(dead_code)] +pub const PUBLIC_KEY_LENGTH_ENCODED: usize = CRYPTO_KEY_LENGTH_ENCODED; /// Length of a secret key in bytes #[allow(dead_code)] -pub const SECRET_KEY_LENGTH: usize = 32; +pub const SECRET_KEY_LENGTH: usize = CRYPTO_KEY_LENGTH; /// Length of a secret key in bytes after encoding to base64url #[allow(dead_code)] -pub const SECRET_KEY_LENGTH_ENCODED: usize = 43; +pub const SECRET_KEY_LENGTH_ENCODED: usize = CRYPTO_KEY_LENGTH_ENCODED; /// Length of a signature in bytes #[allow(dead_code)] pub const SIGNATURE_LENGTH: usize = 64; @@ -35,22 +41,22 @@ pub const NONCE_LENGTH: usize = 24; pub const NONCE_LENGTH_ENCODED: usize = 32; /// Length of a shared secret in bytes #[allow(dead_code)] -pub const SHARED_SECRET_LENGTH: usize = 32; +pub const SHARED_SECRET_LENGTH: usize = CRYPTO_KEY_LENGTH; /// Length of a shared secret in bytes after encoding to base64url #[allow(dead_code)] -pub const SHARED_SECRET_LENGTH_ENCODED: usize = 43; +pub const SHARED_SECRET_LENGTH_ENCODED: usize = CRYPTO_KEY_LENGTH_ENCODED; /// Length of a route id in bytes #[allow(dead_code)] -pub const ROUTE_ID_LENGTH: usize = 32; +pub const ROUTE_ID_LENGTH: usize = CRYPTO_KEY_LENGTH; /// Length of a route id in bytes afer encoding to base64url #[allow(dead_code)] -pub const ROUTE_ID_LENGTH_ENCODED: usize = 43; +pub const ROUTE_ID_LENGTH_ENCODED: usize = CRYPTO_KEY_LENGTH_ENCODED; /// Length of a hash digest in bytes #[allow(dead_code)] -pub const HASH_DIGEST_LENGTH: usize = 32; +pub const HASH_DIGEST_LENGTH: usize = CRYPTO_KEY_LENGTH; /// Length of a hash digest in bytes after encoding to base64url #[allow(dead_code)] -pub const HASH_DIGEST_LENGTH_ENCODED: usize = 43; +pub const HASH_DIGEST_LENGTH_ENCODED: usize = CRYPTO_KEY_LENGTH_ENCODED; ////////////////////////////////////////////////////////////////////// @@ -255,18 +261,14 @@ macro_rules! byte_array_type { ///////////////////////////////////////// -byte_array_type!(PublicKey, PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH_ENCODED); -byte_array_type!(SecretKey, SECRET_KEY_LENGTH, SECRET_KEY_LENGTH_ENCODED); +byte_array_type!(CryptoKey, CRYPTO_KEY_LENGTH, CRYPTO_KEY_LENGTH_ENCODED); + +pub type PublicKey = CryptoKey; +pub type SecretKey = CryptoKey; +pub type HashDigest = CryptoKey; +pub type SharedSecret = CryptoKey; +pub type RouteId = CryptoKey; +pub type CryptoKeyDistance = CryptoKey; + byte_array_type!(Signature, SIGNATURE_LENGTH, SIGNATURE_LENGTH_ENCODED); -byte_array_type!( - PublicKeyDistance, - PUBLIC_KEY_LENGTH, - PUBLIC_KEY_LENGTH_ENCODED -); byte_array_type!(Nonce, NONCE_LENGTH, NONCE_LENGTH_ENCODED); -byte_array_type!( - SharedSecret, - SHARED_SECRET_LENGTH, - SHARED_SECRET_LENGTH_ENCODED -); -byte_array_type!(RouteId, ROUTE_ID_LENGTH, ROUTE_ID_LENGTH_ENCODED); diff --git a/veilid-core/src/crypto/crypto_system.rs b/veilid-core/src/crypto/crypto_system.rs index 5de8fb57..84ac60a6 100644 --- a/veilid-core/src/crypto/crypto_system.rs +++ b/veilid-core/src/crypto/crypto_system.rs @@ -21,23 +21,23 @@ pub trait CryptoSystem { secret: &SecretKey, ) -> Result; fn generate_keypair(&self) -> KeyPair; - fn generate_hash(&self, data: &[u8]) -> PublicKey; + fn generate_hash(&self, data: &[u8]) -> HashDigest; fn generate_hash_reader( &self, reader: &mut dyn std::io::Read, - ) -> Result; + ) -> Result; // Validation - fn validate_keypair(&self, dht_key: &PublicKey, dht_key_secret: &SecretKey) -> bool; - fn validate_hash(&self, data: &[u8], dht_key: &PublicKey) -> bool; + fn validate_keypair(&self, key: &PublicKey, secret: &SecretKey) -> bool; + fn validate_hash(&self, data: &[u8], hash: &HashDigest) -> bool; fn validate_hash_reader( &self, reader: &mut dyn std::io::Read, - key: &PublicKey, + hash: &HashDigest, ) -> Result; // Distance Metric - fn distance(&self, key1: &PublicKey, key2: &PublicKey) -> PublicKeyDistance; + fn distance(&self, key1: &CryptoKey, key2: &CryptoKey) -> CryptoKeyDistance; // Authentication fn sign( diff --git a/veilid-core/src/crypto/none/mod.rs b/veilid-core/src/crypto/none/mod.rs index e4109b77..f59944ea 100644 --- a/veilid-core/src/crypto/none/mod.rs +++ b/veilid-core/src/crypto/none/mod.rs @@ -139,14 +139,14 @@ impl CryptoSystem for CryptoSystemNONE { Ok(bytes == dht_key.bytes) } // Distance Metric - fn distance(&self, key1: &PublicKey, key2: &PublicKey) -> PublicKeyDistance { + fn distance(&self, key1: &PublicKey, key2: &PublicKey) -> CryptoKeyDistance { let mut bytes = [0u8; PUBLIC_KEY_LENGTH]; for (n, byte) in bytes.iter_mut().enumerate() { *byte = key1.bytes[n] ^ key2.bytes[n]; } - PublicKeyDistance::new(bytes) + CryptoKeyDistance::new(bytes) } // Authentication diff --git a/veilid-core/src/crypto/vld0/mod.rs b/veilid-core/src/crypto/vld0/mod.rs index c8539381..cebe9a2b 100644 --- a/veilid-core/src/crypto/vld0/mod.rs +++ b/veilid-core/src/crypto/vld0/mod.rs @@ -134,14 +134,14 @@ impl CryptoSystem for CryptoSystemVLD0 { Ok(bytes == dht_key.bytes) } // Distance Metric - fn distance(&self, key1: &PublicKey, key2: &PublicKey) -> PublicKeyDistance { + fn distance(&self, key1: &PublicKey, key2: &PublicKey) -> CryptoKeyDistance { let mut bytes = [0u8; PUBLIC_KEY_LENGTH]; for (n, byte) in bytes.iter_mut().enumerate() { *byte = key1.bytes[n] ^ key2.bytes[n]; } - PublicKeyDistance::new(bytes) + CryptoKeyDistance::new(bytes) } // Authentication diff --git a/veilid-core/src/rpc_processor/rpc_app_call.rs b/veilid-core/src/rpc_processor/rpc_app_call.rs index 2ec9a24b..80919d4c 100644 --- a/veilid-core/src/rpc_processor/rpc_app_call.rs +++ b/veilid-core/src/rpc_processor/rpc_app_call.rs @@ -61,7 +61,7 @@ impl RPCProcessor { let sender = msg .opt_sender_nr .as_ref() - .map(|nr| nr.node_ids().get(crypto_kind).unwrap().value); + .map(|nr| nr.node_ids().get(crypto_kind).unwrap()); // Register a waiter for this app call let handle = self diff --git a/veilid-core/src/rpc_processor/rpc_app_message.rs b/veilid-core/src/rpc_processor/rpc_app_message.rs index e8454f79..726515a4 100644 --- a/veilid-core/src/rpc_processor/rpc_app_message.rs +++ b/veilid-core/src/rpc_processor/rpc_app_message.rs @@ -38,7 +38,7 @@ impl RPCProcessor { let sender = msg .opt_sender_nr .as_ref() - .map(|nr| nr.node_ids().get(crypto_kind).unwrap().value); + .map(|nr| nr.node_ids().get(crypto_kind).unwrap()); // Pass the message up through the update callback let message = app_message.destructure(); diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index b37142b3..191fce92 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -392,7 +392,7 @@ impl StorageManager { pub async fn watch_values( &self, key: TypedKey, - subkeys: &[ValueSubkeyRange], + subkeys: ValueSubkeyRangeSet, expiration: Timestamp, count: u32, ) -> Result { @@ -403,7 +403,7 @@ impl StorageManager { pub async fn cancel_watch_values( &self, key: TypedKey, - subkeys: &[ValueSubkeyRange], + subkeys: ValueSubkeyRangeSet, ) -> Result { let inner = self.lock().await?; unimplemented!(); diff --git a/veilid-core/src/veilid_api/routing_context.rs b/veilid-core/src/veilid_api/routing_context.rs index fd06b286..d7ba5e2c 100644 --- a/veilid-core/src/veilid_api/routing_context.rs +++ b/veilid-core/src/veilid_api/routing_context.rs @@ -277,7 +277,7 @@ impl RoutingContext { pub async fn watch_dht_values( &self, key: TypedKey, - subkeys: &[ValueSubkeyRange], + subkeys: ValueSubkeyRangeSet, expiration: Timestamp, count: u32, ) -> Result { @@ -292,7 +292,7 @@ impl RoutingContext { pub async fn cancel_dht_watch( &self, key: TypedKey, - subkeys: &[ValueSubkeyRange], + subkeys: ValueSubkeyRangeSet, ) -> Result { let storage_manager = self.api.storage_manager()?; storage_manager.cancel_watch_values(key, subkeys).await diff --git a/veilid-core/src/veilid_api/types/app_message_call.rs b/veilid-core/src/veilid_api/types/app_message_call.rs index eb3b99e0..6f0805fe 100644 --- a/veilid-core/src/veilid_api/types/app_message_call.rs +++ b/veilid-core/src/veilid_api/types/app_message_call.rs @@ -8,7 +8,7 @@ use super::*; pub struct VeilidAppMessage { /// Some(sender) if the message was sent directly, None if received via a private/safety route #[serde(with = "opt_json_as_string")] - sender: Option, xxx continue propagating this publickey->typedkey and get all the FFI done + sender: Option, /// The content of the message to deliver to the application #[serde(with = "json_as_base64")] message: Vec, diff --git a/veilid-core/src/veilid_api/types/fourcc.rs b/veilid-core/src/veilid_api/types/fourcc.rs index c634b796..edce2b03 100644 --- a/veilid-core/src/veilid_api/types/fourcc.rs +++ b/veilid-core/src/veilid_api/types/fourcc.rs @@ -24,6 +24,19 @@ impl From<[u8; 4]> for FourCC { Self(b) } } + +impl From for FourCC { + fn from(u: u32) -> Self { + Self(u.to_be_bytes()) + } +} + +impl From for u32 { + fn from(u: FourCC) -> Self { + u32::from_be_bytes(u.0) + } +} + impl TryFrom<&[u8]> for FourCC { type Error = VeilidAPIError; fn try_from(b: &[u8]) -> Result { diff --git a/veilid-flutter/lib/routing_context.dart b/veilid-flutter/lib/routing_context.dart index 83414671..7fc15526 100644 --- a/veilid-flutter/lib/routing_context.dart +++ b/veilid-flutter/lib/routing_context.dart @@ -4,7 +4,7 @@ import 'dart:convert'; import 'package:change_case/change_case.dart'; -import 'base64url_no_pad.dart'; +import 'veilid_encoding.dart'; import 'veilid.dart'; ////////////////////////////////////// @@ -58,7 +58,7 @@ class DHTSchemaDFLT implements DHTSchema { } class DHTSchemaMember { - Key mKey; + PublicKey mKey; int mCnt; DHTSchemaMember({ @@ -111,8 +111,8 @@ class DHTSchemaSMPL implements DHTSchema { class DHTRecordDescriptor { TypedKey key; - Key owner; - Key? ownerSecret; + PublicKey owner; + PublicKey? ownerSecret; DHTSchema schema; DHTRecordDescriptor({ @@ -179,7 +179,7 @@ class ValueSubkeyRange { class ValueData { final int seq; final Uint8List data; - final Key writer; + final PublicKey writer; ValueData({ required this.seq, diff --git a/veilid-flutter/lib/veilid.dart b/veilid-flutter/lib/veilid.dart index 181153a6..e716b22b 100644 --- a/veilid-flutter/lib/veilid.dart +++ b/veilid-flutter/lib/veilid.dart @@ -127,13 +127,13 @@ abstract class Veilid { // Crypto List validCryptoKinds(); - VeilidCryptoSystem getCryptoSystem(CryptoKind kind); - VeilidCryptoSystem bestCryptoSystem(); - List verifySignatures( + Future getCryptoSystem(CryptoKind kind); + Future bestCryptoSystem(); + Future> verifySignatures( List nodeIds, Uint8List data, List signatures); - List generateSignatures( + Future> generateSignatures( Uint8List data, List keyPairs); - TypedKeyPair generateKeyPair(CryptoKind kind); + Future generateKeyPair(CryptoKind kind); // Routing context Future routingContext(); diff --git a/veilid-flutter/lib/veilid_config.dart b/veilid-flutter/lib/veilid_config.dart index ce9e0380..7f5d0787 100644 --- a/veilid-flutter/lib/veilid_config.dart +++ b/veilid-flutter/lib/veilid_config.dart @@ -450,8 +450,8 @@ class VeilidConfigRPC { //////////// class VeilidConfigRoutingTable { - List nodeId; - List nodeIdSecret; + List nodeId; + List nodeIdSecret; List bootstrap; int limitOverAttached; int limitFullyAttached; @@ -484,9 +484,10 @@ class VeilidConfigRoutingTable { } VeilidConfigRoutingTable.fromJson(dynamic json) - : nodeId = List.from(json['node_id'].map((j) => Key.fromJson(j))), - nodeIdSecret = - List.from(json['node_id_secret'].map((j) => Key.fromJson(j))), + : nodeId = List.from( + json['node_id'].map((j) => PublicKey.fromJson(j))), + nodeIdSecret = List.from( + json['node_id_secret'].map((j) => PublicKey.fromJson(j))), bootstrap = List.from(json['bootstrap'].map((j) => j)), limitOverAttached = json['limit_over_attached'], limitFullyAttached = json['limit_fully_attached'], diff --git a/veilid-flutter/lib/veilid_crypto.dart b/veilid-flutter/lib/veilid_crypto.dart index e18adee7..40be7f74 100644 --- a/veilid-flutter/lib/veilid_crypto.dart +++ b/veilid-flutter/lib/veilid_crypto.dart @@ -63,8 +63,8 @@ class Typed { } class KeyPair { - late Key key; - late Key secret; + late PublicKey key; + late PublicKey secret; KeyPair({required this.key, required this.secret}); @override @@ -79,8 +79,8 @@ class KeyPair { parts[1].codeUnits.length != 43) { throw const FormatException("malformed string"); } - key = Key(parts[0]); - secret = Key(parts[1]); + key = PublicKey(parts[0]); + secret = PublicKey(parts[1]); } String get json { @@ -92,8 +92,8 @@ class KeyPair { class TypedKeyPair { late CryptoKind kind; - late Key key; - late Key secret; + late PublicKey key; + late PublicKey secret; TypedKeyPair({required this.kind, required this.key, required this.secret}); @override @@ -110,8 +110,8 @@ class TypedKeyPair { throw VeilidAPIExceptionInvalidArgument("malformed string", "s", s); } kind = cryptoKindFromString(parts[0]); - key = Key(parts[1]); - secret = Key(parts[2]); + key = PublicKey(parts[1]); + secret = PublicKey(parts[2]); } String get json { @@ -121,11 +121,17 @@ class TypedKeyPair { TypedKeyPair.fromJson(dynamic json) : this.fromString(json as String); } -typedef Key = FixedEncodedString43; +typedef CryptoKey = FixedEncodedString43; typedef Signature = FixedEncodedString86; typedef Nonce = FixedEncodedString32; -typedef TypedKey = Typed; +typedef PublicKey = CryptoKey; +typedef SecretKey = CryptoKey; +typedef HashDigest = CryptoKey; +typedef SharedSecret = CryptoKey; +typedef CryptoKeyDistance = CryptoKey; + +typedef TypedKey = Typed; typedef TypedSignature = Typed; ////////////////////////////////////// @@ -133,23 +139,24 @@ typedef TypedSignature = Typed; abstract class VeilidCryptoSystem { CryptoKind kind(); - Key cachedDH(Key key, Key secret); - Key computeDH(Key key, Key secret); - Nonce randomNonce(); - Key randomSharedSecret(); - KeyPair generateKeyPair(); - Key generateHash(Uint8List data); - Key generateHashReader(Stream> reader); - bool validateKeyPair(Key key, Key secret); - bool validateHash(Uint8List data, Key hash); - bool validateHashReader(Stream> reader, Key hash); - Key distance(Key key1, Key key2); - Signature sign(Key key, Key secret, Uint8List data); - void verify(Key key, Uint8List data, Signature signature); - BigInt aeadOverhead(); - Uint8List decryptAead( - Uint8List body, Nonce nonce, Key sharedSecret, Uint8List? associatedData); - Uint8List encryptAead( - Uint8List body, Nonce nonce, Key sharedSecret, Uint8List? associatedData); - Uint8List cryptNoAuth(Uint8List body, Nonce nonce, Key sharedSecret); + Future cachedDH(PublicKey key, SecretKey secret); + Future computeDH(PublicKey key, SecretKey secret); + Future randomNonce(); + Future randomSharedSecret(); + Future generateKeyPair(); + Future generateHash(Uint8List data); + Future generateHashReader(Stream> reader); + Future validateKeyPair(PublicKey key, SecretKey secret); + Future validateHash(Uint8List data, HashDigest hash); + Future validateHashReader(Stream> reader, HashDigest hash); + Future distance(CryptoKey key1, CryptoKey key2); + Future sign(PublicKey key, SecretKey secret, Uint8List data); + Future verify(PublicKey key, Uint8List data, Signature signature); + Future aeadOverhead(); + Future decryptAead(Uint8List body, Nonce nonce, + SharedSecret sharedSecret, Uint8List? associatedData); + Future encryptAead(Uint8List body, Nonce nonce, + SharedSecret sharedSecret, Uint8List? associatedData); + Future cryptNoAuth( + Uint8List body, Nonce nonce, SharedSecret sharedSecret); } diff --git a/veilid-flutter/lib/veilid_ffi.dart b/veilid-flutter/lib/veilid_ffi.dart index 2bb17d96..a1c352ca 100644 --- a/veilid-flutter/lib/veilid_ffi.dart +++ b/veilid-flutter/lib/veilid_ffi.dart @@ -8,7 +8,7 @@ import 'dart:typed_data'; import 'package:ffi/ffi.dart'; import 'veilid.dart'; -import 'base64url_no_pad.dart'; +import 'veilid_encoding.dart'; ////////////////////////////////////////////////////////// // FFI Platform-specific config @@ -189,6 +189,46 @@ typedef _RoutingContextAppMessageC = Void Function( Int64, Uint32, Pointer, Pointer); typedef _RoutingContextAppMessageDart = void Function( int, int, Pointer, Pointer); +// fn routing_context_create_dht_record(port: i64, id: u32, kind: u32, schema: FfiStr) +typedef _RoutingContextCreateDHTRecordC = Void Function( + Int64, Uint32, Uint32, Pointer); +typedef _RoutingContextCreateDHTRecordDart = void Function( + int, int, int, Pointer); +// fn routing_context_open_dht_record(port: i64, id: u32, key: FfiStr, writer: FfiStr) +typedef _RoutingContextOpenDHTRecordC = Void Function( + Int64, Uint32, Pointer, Pointer); +typedef _RoutingContextOpenDHTRecordDart = void Function( + int, int, Pointer, Pointer); +// fn routing_context_close_dht_record(port: i64, id: u32, key: FfiStr) +typedef _RoutingContextCloseDHTRecordC = Void Function( + Int64, Uint32, Pointer); +typedef _RoutingContextCloseDHTRecordDart = void Function( + int, int, Pointer); +// fn routing_context_delete_dht_record(port: i64, id: u32, key: FfiStr) +typedef _RoutingContextDeleteDHTRecordC = Void Function( + Int64, Uint32, Pointer); +typedef _RoutingContextDeleteDHTRecordDart = void Function( + int, int, Pointer); +// fn routing_context_get_dht_value(port: i64, id: u32, key: FfiStr, subkey: u32, force_refresh: bool) +typedef _RoutingContextGetDHTValueC = Void Function( + Int64, Uint32, Pointer, Uint32, Bool); +typedef _RoutingContextGetDHTValueDart = void Function( + int, int, Pointer, int, bool); +// fn routing_context_set_dht_value(port: i64, id: u32, key: FfiStr, subkey: u32, data: FfiStr) +typedef _RoutingContextSetDHTValueC = Void Function( + Int64, Uint32, Pointer, Uint32, Pointer); +typedef _RoutingContextSetDHTValueDart = void Function( + int, int, Pointer, int, Pointer); +// fn routing_context_watch_dht_values(port: i64, id: u32, key: FfiStr, subkeys: FfiStr, expiration: FfiStr, count: u32) +typedef _RoutingContextWatchDHTValuesC = Void Function( + Int64, Uint32, Pointer, Pointer, Pointer, Uint32); +typedef _RoutingContextWatchDHTValuesDart = void Function( + int, int, Pointer, Pointer, Pointer, int); +// fn routing_context_cancel_dht_watch(port: i64, id: u32, key: FfiStr, subkeys: FfiStr) +typedef _RoutingContextCancelDHTWatchC = Void Function( + Int64, Uint32, Pointer, Pointer); +typedef _RoutingContextCancelDHTWatchDart = void Function( + int, int, Pointer, Pointer); // fn new_private_route(port: i64) typedef _NewPrivateRouteC = Void Function(Int64); @@ -257,7 +297,94 @@ typedef _TableDbTransactionDeleteC = Void Function( Int64, Uint32, Uint32, Pointer); typedef _TableDbTransactionDeleteDart = void Function( int, int, int, Pointer); +// fn valid_crypto_kinds() -> *mut c_char +typedef _ValidCryptoKindsC = Pointer Function(); +typedef _ValidCryptoKindsDart = Pointer Function(); +// fn best_crypto_kind() -> u32 +typedef _BestCryptoKindC = Uint32 Function(); +typedef _BestCryptoKindDart = int Function(); +// fn verify_signatures(port: i64, node_ids: FfiStr, data: FfiStr, signatures: FfiStr) +typedef _VerifySignaturesC = Void Function( + Int64, Pointer, Pointer, Pointer); +typedef _VerifySignaturesDart = void Function( + int, Pointer, Pointer, Pointer); +// fn generate_signatures(port: i64, data: FfiStr, key_pairs: FfiStr) +typedef _GenerateSignaturesC = Void Function( + Int64, Pointer, Pointer); +typedef _GenerateSignaturesDart = void Function( + int, Pointer, Pointer); +// fn generate_key_pair(port: i64, kind: u32) { +typedef _GenerateKeyPairC = Void Function(Int64, Uint32); +typedef _GenerateKeyPairDart = void Function(int, int); +// fn crypto_cached_dh(port: i64, kind: u32, key: FfiStr, secret: FfiStr) +typedef _CryptoCachedDHC = Void Function( + Int64, Uint32, Pointer, Pointer); +typedef _CryptoCachedDHDart = void Function( + int, int, Pointer, Pointer); +// fn crypto_compute_dh(port: i64, kind: u32, key: FfiStr, secret: FfiStr) +typedef _CryptoComputeDHC = Void Function( + Int64, Uint32, Pointer, Pointer); +typedef _CryptoComputeDHDart = void Function( + int, int, Pointer, Pointer); +// fn crypto_random_nonce(port: i64, kind: u32) +typedef _CryptoRandomNonceC = Void Function(Int64, Uint32); +typedef _CryptoRandomNonceDart = void Function(int, int); +// fn crypto_random_shared_secret(port: i64, kind: u32) +typedef _CryptoRandomSharedSecretC = Void Function(Int64, Uint32); +typedef _CryptoRandomSharedSecretDart = void Function(int, int); +// fn crypto_generate_key_pair(port: i64, kind: u32) +typedef _CryptoGenerateKeyPairC = Void Function(Int64, Uint32); +typedef _CryptoGenerateKeyPairDart = void Function(int, int); +// fn crypto_generate_hash(port: i64, kind: u32, data: FfiStr) +typedef _CryptoGenerateHashC = Void Function(Int64, Uint32, Pointer); +typedef _CryptoGenerateHashDart = void Function(int, int, Pointer); +// fn crypto_validate_key_pair(port: i64, kind: u32, key: FfiStr, secret: FfiStr) +typedef _CryptoValidateKeyPairC = Void Function( + Int64, Uint32, Pointer, Pointer); +typedef _CryptoValidateKeyPairDart = void Function( + int, int, Pointer, Pointer); +// fn crypto_validate_hash(port: i64, kind: u32, data: FfiStr, hash: FfiStr) +typedef _CryptoValidateHashC = Void Function( + Int64, Uint32, Pointer, Pointer); +typedef _CryptoValidateHashDart = void Function( + int, int, Pointer, Pointer); +// fn crypto_distance(port: i64, kind: u32, key1: FfiStr, key2: FfiStr) +typedef _CryptoDistanceC = Void Function( + Int64, Uint32, Pointer, Pointer); +typedef _CryptoDistanceDart = void Function( + int, int, Pointer, Pointer); +// fn crypto_sign(port: i64, kind: u32, key: FfiStr, secret: FfiStr, data: FfiStr) +typedef _CryptoSignC = Void Function( + Int64, Uint32, Pointer, Pointer, Pointer); +typedef _CryptoSignDart = void Function( + int, int, Pointer, Pointer, Pointer); +// fn crypto_verify(port: i64, kind: u32, key: FfiStr, data: FfiStr, signature: FfiStr) +typedef _CryptoVerifyC = Void Function( + Int64, Uint32, Pointer, Pointer, Pointer); +typedef _CryptoVerifyDart = void Function( + int, int, Pointer, Pointer, Pointer); +// fn crypto_aead_overhead(port: i64, kind: u32) +typedef _CryptoAeadOverheadC = Void Function(Int64, Uint32); +typedef _CryptoAeadOverheadDart = void Function(int, int); +// fn crypto_decrypt_aead(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr, associated_data: FfiStr) +typedef _CryptoDecryptAeadC = Void Function( + Int64, Uint32, Pointer, Pointer, Pointer, Pointer); +typedef _CryptoDecryptAeadDart = void Function( + int, int, Pointer, Pointer, Pointer, Pointer); +// fn crypto_encrypt_aead(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr, associated_data: FfiStr) +typedef _CryptoEncryptAeadC = Void Function( + Int64, Uint32, Pointer, Pointer, Pointer, Pointer); +typedef _CryptoEncryptAeadDart = void Function( + int, int, Pointer, Pointer, Pointer, Pointer); +// fn crypto_crypt_no_auth(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr) +typedef _CryptoCryptNoAuthC = Void Function( + Int64, Uint32, Pointer, Pointer, Pointer); +typedef _CryptoCryptNoAuthDart = void Function( + int, int, Pointer, Pointer, Pointer); +// fn now() -> u64 +typedef _NowC = Uint64 Function(); +typedef _NowDart = int Function(); // fn debug(port: i64, log_level: FfiStr) typedef _DebugC = Void Function(Int64, Pointer); typedef _DebugDart = void Function(int, Pointer); @@ -748,14 +875,14 @@ class VeilidFFI implements Veilid { final _RoutingContextWithSequencingDart _routingContextWithSequencing; final _RoutingContextAppCallDart _routingContextAppCall; final _RoutingContextAppMessageDart _routingContextAppMessage; - final _RoutingContextCreateDHTRecordDart _RoutingContextCreateDHTRecord; - final _RoutingContextOpenDHTRecordDart _RoutingContextOpenDHTRecord; - final _RoutingContextCloseDHTRecordDart _RoutingContextCloseDHTRecord; - final _RoutingContextDeleteDHTRecordDart _RoutingContextDeleteDHTRecord; - final _RoutingContextGetDHTValueDart _RoutingContextGetDHTValue; - final _RoutingContextSetDHTValueDart _RoutingContextSetDHTValue; - final _RoutingContextWatchDHTValuesDart _RoutingContextWatchDHTValues; - final _RoutingContextCancelDHTWatchDart _RoutingContextCancelDHTWatch; + final _RoutingContextCreateDHTRecordDart _routingContextCreateDHTRecord; + final _RoutingContextOpenDHTRecordDart _routingContextOpenDHTRecord; + final _RoutingContextCloseDHTRecordDart _routingContextCloseDHTRecord; + final _RoutingContextDeleteDHTRecordDart _routingContextDeleteDHTRecord; + final _RoutingContextGetDHTValueDart _routingContextGetDHTValue; + final _RoutingContextSetDHTValueDart _routingContextSetDHTValue; + final _RoutingContextWatchDHTValuesDart _routingContextWatchDHTValues; + final _RoutingContextCancelDHTWatchDart _routingContextCancelDHTWatch; final _NewPrivateRouteDart _newPrivateRoute; final _NewCustomPrivateRouteDart _newCustomPrivateRoute; @@ -780,8 +907,7 @@ class VeilidFFI implements Veilid { final _TableDbTransactionDeleteDart _tableDbTransactionDelete; final _ValidCryptoKindsDart _validCryptoKinds; - final _GetCryptoSystemDart _getCryptoSystem; - final _BestCryptoSystemDart _bestCryptoSystem; + final _BestCryptoKindDart _bestCryptoKind; final _VerifySignaturesDart _verifySignatures; final _GenerateSignaturesDart _generateSignatures; final _GenerateKeyPairDart _generateKeyPair; @@ -792,14 +918,12 @@ class VeilidFFI implements Veilid { final _CryptoRandomSharedSecretDart _cryptoRandomSharedSecret; final _CryptoGenerateKeyPairDart _cryptoGenerateKeyPair; final _CryptoGenerateHashDart _cryptoGenerateHash; - final _CryptoGenerateHashReaderDart _cryptoGenerateHashReader; final _CryptoValidateKeyPairDart _cryptoValidateKeyPair; final _CryptoValidateHashDart _cryptoValidateHash; - final _CryptoValidateHashReaderDart _cryptoValidateHashReader; final _CryptoDistanceDart _cryptoDistance; final _CryptoSignDart _cryptoSign; final _CryptoVerifyDart _cryptoVerify; - final _CryptoAaedOverheadDart _cryptoAeadOverhead; + final _CryptoAeadOverheadDart _cryptoAeadOverhead; final _CryptoDecryptAeadDart _cryptoDecryptAead; final _CryptoEncryptAeadDart _cryptoEncryptAead; final _CryptoCryptNoAuthDart _cryptoCryptNoAuth; @@ -850,6 +974,36 @@ class VeilidFFI implements Veilid { _routingContextAppMessage = dylib.lookupFunction< _RoutingContextAppMessageC, _RoutingContextAppMessageDart>('routing_context_app_message'), + _routingContextCreateDHTRecord = dylib.lookupFunction< + _RoutingContextCreateDHTRecordC, + _RoutingContextCreateDHTRecordDart>( + 'routing_context_create_dht_record'), + _routingContextOpenDHTRecord = dylib.lookupFunction< + _RoutingContextOpenDHTRecordC, + _RoutingContextOpenDHTRecordDart>( + 'routing_context_open_dht_record'), + _routingContextCloseDHTRecord = dylib.lookupFunction< + _RoutingContextCloseDHTRecordC, + _RoutingContextCloseDHTRecordDart>( + 'routing_context_close_dht_record'), + _routingContextDeleteDHTRecord = dylib.lookupFunction< + _RoutingContextDeleteDHTRecordC, + _RoutingContextDeleteDHTRecordDart>( + 'routing_context_delete_dht_record'), + _routingContextGetDHTValue = dylib.lookupFunction< + _RoutingContextGetDHTValueC, + _RoutingContextGetDHTValueDart>('routing_context_get_dht_value'), + _routingContextSetDHTValue = dylib.lookupFunction< + _RoutingContextSetDHTValueC, + _RoutingContextSetDHTValueDart>('routing_context_set_dht_value'), + _routingContextWatchDHTValues = dylib.lookupFunction< + _RoutingContextWatchDHTValuesC, + _RoutingContextWatchDHTValuesDart>( + 'routing_context_watch_dht_values'), + _routingContextCancelDHTWatch = dylib.lookupFunction< + _RoutingContextCancelDHTWatchC, + _RoutingContextCancelDHTWatchDart>( + 'routing_context_cancel_dht_watch'), _newPrivateRoute = dylib.lookupFunction<_NewPrivateRouteC, _NewPrivateRouteDart>( 'new_private_route'), @@ -900,6 +1054,31 @@ class VeilidFFI implements Veilid { _tableDbTransactionDelete = dylib.lookupFunction< _TableDbTransactionDeleteC, _TableDbTransactionDeleteDart>('table_db_transaction_delete'), + +xxx + final _ValidCryptoKindsDart _validCryptoKinds; + final _BestCryptoKindDart _bestCryptoKind; + final _VerifySignaturesDart _verifySignatures; + final _GenerateSignaturesDart _generateSignatures; + final _GenerateKeyPairDart _generateKeyPair; + + final _CryptoCachedDHDart _cryptoCachedDH; + final _CryptoComputeDHDart _cryptoComputeDH; + final _CryptoRandomNonceDart _cryptoRandomNonce; + final _CryptoRandomSharedSecretDart _cryptoRandomSharedSecret; + final _CryptoGenerateKeyPairDart _cryptoGenerateKeyPair; + final _CryptoGenerateHashDart _cryptoGenerateHash; + final _CryptoValidateKeyPairDart _cryptoValidateKeyPair; + final _CryptoValidateHashDart _cryptoValidateHash; + final _CryptoDistanceDart _cryptoDistance; + final _CryptoSignDart _cryptoSign; + final _CryptoVerifyDart _cryptoVerify; + final _CryptoAeadOverheadDart _cryptoAeadOverhead; + final _CryptoDecryptAeadDart _cryptoDecryptAead; + final _CryptoEncryptAeadDart _cryptoEncryptAead; + final _CryptoCryptNoAuthDart _cryptoCryptNoAuth; + + _debug = dylib.lookupFunction<_DebugC, _DebugDart>('debug'), _veilidVersionString = dylib.lookupFunction<_VeilidVersionStringC, _VeilidVersionStringDart>('veilid_version_string'), diff --git a/veilid-flutter/lib/veilid_js.dart b/veilid-flutter/lib/veilid_js.dart index ae6d6ac0..0125236a 100644 --- a/veilid-flutter/lib/veilid_js.dart +++ b/veilid-flutter/lib/veilid_js.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; -import 'base64url_no_pad.dart'; +import 'veilid_encoding.dart'; ////////////////////////////////////////////////////////// // WASM Platform-specific config diff --git a/veilid-flutter/lib/veilid_state.dart b/veilid-flutter/lib/veilid_state.dart index 344f3f47..a1248f3f 100644 --- a/veilid-flutter/lib/veilid_state.dart +++ b/veilid-flutter/lib/veilid_state.dart @@ -373,7 +373,7 @@ class VeilidLog implements VeilidUpdate { } class VeilidAppMessage implements VeilidUpdate { - final String? sender; + final TypedKey? sender; final Uint8List message; // diff --git a/veilid-flutter/rust/src/dart_ffi.rs b/veilid-flutter/rust/src/dart_ffi.rs index 841c030f..3f341912 100644 --- a/veilid-flutter/rust/src/dart_ffi.rs +++ b/veilid-flutter/rust/src/dart_ffi.rs @@ -494,10 +494,10 @@ pub extern "C" fn routing_context_app_message(port: i64, id: u32, target: FfiStr #[no_mangle] pub extern "C" fn routing_context_create_dht_record(port: i64, id: u32, kind: u32, schema: FfiStr) { - let crypto_kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind.to_be_bytes()); + let crypto_kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); let schema: veilid_core::DHTSchema = veilid_core::deserialize_opt_json(schema.into_opt_string()).unwrap(); - DartIsolateWrapper::new(port).spawn_result(async move { + DartIsolateWrapper::new(port).spawn_result_json(async move { let routing_context = { let rc = ROUTING_CONTEXTS.lock(); let Some(routing_context) = rc.get(&id) else { @@ -507,16 +507,15 @@ pub extern "C" fn routing_context_create_dht_record(port: i64, id: u32, kind: u3 }; let dht_record_descriptor = routing_context.create_dht_record(crypto_kind, schema).await?; - let out = veilid_core::serialize_json(dht_record_descriptor); - APIResult::Ok(out) + APIResult::Ok(dht_record_descriptor) }); } #[no_mangle] pub extern "C" fn routing_context_open_dht_record(port: i64, id: u32, key: FfiStr, writer: FfiStr) { let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); - let writer: Option = writer.into_opt_string().map(|s| veilid_core::deserialize_json(&s).unwrap()); - DartIsolateWrapper::new(port).spawn_result(async move { + let writer: Option = writer.into_opt_string().map(|s| veilid_core::deserialize_json(&s).unwrap()); + DartIsolateWrapper::new(port).spawn_result_json(async move { let routing_context = { let rc = ROUTING_CONTEXTS.lock(); let Some(routing_context) = rc.get(&id) else { @@ -524,31 +523,125 @@ pub extern "C" fn routing_context_open_dht_record(port: i64, id: u32, key: FfiSt }; routing_context.clone() }; - let writer = match writer { - Some(w) => w.to_key_pair(key.kind)?, - None => None - }; let dht_record_descriptor = routing_context.open_dht_record(key, writer).await?; - let out = veilid_core::serialize_json(dht_record_descriptor); - APIResult::Ok(out) + APIResult::Ok(dht_record_descriptor) }); } - -// final _RoutingContextCloseDHTRecordDart _RoutingContextCloseDHTRecord; -// final _RoutingContextDeleteDHTRecordDart _RoutingContextDeleteDHTRecord; -// final _RoutingContextGetDHTValueDart _RoutingContextGetDHTValue; -// final _RoutingContextSetDHTValueDart _RoutingContextSetDHTValue; -// final _RoutingContextWatchDHTValuesDart _RoutingContextWatchDHTValues; -// final _RoutingContextCancelDHTWatchDart _RoutingContextCancelDHTWatch; +#[no_mangle] +pub extern "C" fn routing_context_close_dht_record(port: i64, id: u32, key: FfiStr) { + let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + DartIsolateWrapper::new(port).spawn_result(async move { + let routing_context = { + let rc = ROUTING_CONTEXTS.lock(); + let Some(routing_context) = rc.get(&id) else { + return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_close_dht_record", "id", id)); + }; + routing_context.clone() + }; + routing_context.close_dht_record(key).await?; + APIRESULT_VOID + }); +} +#[no_mangle] +pub extern "C" fn routing_context_delete_dht_record(port: i64, id: u32, key: FfiStr) { + let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + DartIsolateWrapper::new(port).spawn_result(async move { + let routing_context = { + let rc = ROUTING_CONTEXTS.lock(); + let Some(routing_context) = rc.get(&id) else { + return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_delete_dht_record", "id", id)); + }; + routing_context.clone() + }; + routing_context.delete_dht_record(key).await?; + APIRESULT_VOID + }); +} +#[no_mangle] +pub extern "C" fn routing_context_get_dht_value(port: i64, id: u32, key: FfiStr, subkey: u32, force_refresh: bool) { + let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + DartIsolateWrapper::new(port).spawn_result_json(async move { + let routing_context = { + let rc = ROUTING_CONTEXTS.lock(); + let Some(routing_context) = rc.get(&id) else { + return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_get_dht_value", "id", id)); + }; + routing_context.clone() + }; + let res = routing_context.get_dht_value(key, subkey, force_refresh).await?; + APIResult::Ok(res) + }); +} +#[no_mangle] +pub extern "C" fn routing_context_set_dht_value(port: i64, id: u32, key: FfiStr, subkey: u32, data: FfiStr) { + let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let data: Vec = data_encoding::BASE64URL_NOPAD + .decode( + data.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + DartIsolateWrapper::new(port).spawn_result_json(async move { + let routing_context = { + let rc = ROUTING_CONTEXTS.lock(); + let Some(routing_context) = rc.get(&id) else { + return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_set_dht_value", "id", id)); + }; + routing_context.clone() + }; + let res = routing_context.set_dht_value(key, subkey, data).await?; + APIResult::Ok(res) + }); +} + + +#[no_mangle] +pub extern "C" fn routing_context_watch_dht_values(port: i64, id: u32, key: FfiStr, subkeys: FfiStr, expiration: FfiStr, count: u32) { + let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let subkeys: veilid_core::ValueSubkeyRangeSet = veilid_core::deserialize_opt_json(subkeys.into_opt_string()).unwrap(); + let expiration = veilid_core::Timestamp::from_str(expiration.as_opt_str().unwrap()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result(async move { + let routing_context = { + let rc = ROUTING_CONTEXTS.lock(); + let Some(routing_context) = rc.get(&id) else { + return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_set_dht_value", "id", id)); + }; + routing_context.clone() + }; + let res = routing_context.watch_dht_values(key, subkeys, expiration, count).await?; + APIResult::Ok(res.to_string()) + }); +} + + +#[no_mangle] +pub extern "C" fn routing_context_cancel_dht_watch(port: i64, id: u32, key: FfiStr, subkeys: FfiStr) { + let key: veilid_core::TypedKey = veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let subkeys: veilid_core::ValueSubkeyRangeSet = veilid_core::deserialize_opt_json(subkeys.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result(async move { + let routing_context = { + let rc = ROUTING_CONTEXTS.lock(); + let Some(routing_context) = rc.get(&id) else { + return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_set_dht_value", "id", id)); + }; + routing_context.clone() + }; + let res = routing_context.cancel_dht_watch(key, subkeys).await?; + APIResult::Ok(res) + }); +} #[no_mangle] @@ -894,34 +987,390 @@ pub extern "C" fn table_db_delete(port: i64, id: u32, col: u32, key: FfiStr) { } +#[no_mangle] +pub extern "C" fn valid_crypto_kinds() -> *mut c_char { + veilid_core::serialize_json(veilid_core::VALID_CRYPTO_KINDS.iter().map(|k| (*k).into()).collect::>()).into_ffi_value() +} -final _ValidCryptoKindsDart _validCryptoKinds; -final _GetCryptoSystemDart _getCryptoSystem; -final _BestCryptoSystemDart _bestCryptoSystem; -final _VerifySignaturesDart _verifySignatures; -final _GenerateSignaturesDart _generateSignatures; -final _GenerateKeyPairDart _generateKeyPair; +#[no_mangle] +pub extern "C" fn best_crypto_kind() -> u32 { + veilid_core::best_crypto_kind().into() +} -final _CryptoCachedDHDart _cryptoCachedDH; -final _CryptoComputeDHDart _cryptoComputeDH; -final _CryptoRandomNonceDart _cryptoRandomNonce; -final _CryptoRandomSharedSecretDart _cryptoRandomSharedSecret; -final _CryptoGenerateKeyPairDart _cryptoGenerateKeyPair; -final _CryptoGenerateHashDart _cryptoGenerateHash; -final _CryptoGenerateHashReaderDart _cryptoGenerateHashReader; -final _CryptoValidateKeyPairDart _cryptoValidateKeyPair; -final _CryptoValidateHashDart _cryptoValidateHash; -final _CryptoValidateHashReaderDart _cryptoValidateHashReader; -final _CryptoDistanceDart _cryptoDistance; -final _CryptoSignDart _cryptoSign; -final _CryptoVerifyDart _cryptoVerify; -final _CryptoAaedOverheadDart _cryptoAeadOverhead; -final _CryptoDecryptAeadDart _cryptoDecryptAead; -final _CryptoEncryptAeadDart _cryptoEncryptAead; -final _CryptoCryptNoAuthDart _cryptoCryptNoAuth; +#[no_mangle] +pub extern "C" fn verify_signatures(port: i64, node_ids: FfiStr, data: FfiStr, signatures: FfiStr) { + let node_ids: Vec = + veilid_core::deserialize_opt_json(node_ids.into_opt_string()).unwrap(); -final _NowDart _now; + let data: Vec = data_encoding::BASE64URL_NOPAD + .decode( + data.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + let typed_signatures: Vec = + veilid_core::deserialize_opt_json(signatures.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let out = crypto.verify_signatures(&node_ids, &data, &typed_signatures)?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn generate_signatures(port: i64, data: FfiStr, key_pairs: FfiStr) { + + let data: Vec = data_encoding::BASE64URL_NOPAD + .decode( + data.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + + let key_pairs: Vec = + veilid_core::deserialize_opt_json(key_pairs.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let out = crypto.generate_signatures(&data, &key_pairs, |k, s| { + veilid_core::TypedSignature::new(k.kind, s) + })?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn generate_key_pair(port: i64, kind: u32) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let out = veilid_core::Crypto::generate_keypair(kind)?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_cached_dh(port: i64, kind: u32, key: FfiStr, secret: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let key: veilid_core::PublicKey = + veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let secret: veilid_core::SecretKey = + veilid_core::deserialize_opt_json(secret.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_cached_dh", "kind", kind.to_string()))?; + let out = csv.cached_dh(&key, &secret)?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_compute_dh(port: i64, kind: u32, key: FfiStr, secret: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let key: veilid_core::PublicKey = + veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let secret: veilid_core::SecretKey = + veilid_core::deserialize_opt_json(secret.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_compute_dh", "kind", kind.to_string()))?; + let out = csv.compute_dh(&key, &secret)?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_random_nonce(port: i64, kind: u32) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_random_nonce", "kind", kind.to_string()))?; + let out = csv.random_nonce(); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_random_shared_secret(port: i64, kind: u32) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_random_shared_secret", "kind", kind.to_string()))?; + let out = csv.random_shared_secret(); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_generate_key_pair(port: i64, kind: u32) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_generate_key_pair", "kind", kind.to_string()))?; + let out = csv.generate_keypair(); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_generate_hash(port: i64, kind: u32, data: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let data: Vec = data_encoding::BASE64URL_NOPAD + .decode( + data.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_generate_hash", "kind", kind.to_string()))?; + let out = csv.generate_hash(&data); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_validate_key_pair(port: i64, kind: u32, key: FfiStr, secret: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let key: veilid_core::PublicKey = + veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let secret: veilid_core::SecretKey = + veilid_core::deserialize_opt_json(secret.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_validate_key_pair", "kind", kind.to_string()))?; + let out = csv.validate_keypair(&key, &secret); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_validate_hash(port: i64, kind: u32, data: FfiStr, hash: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let data: Vec = data_encoding::BASE64URL_NOPAD + .decode( + data.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + + let hash: veilid_core::HashDigest = + veilid_core::deserialize_opt_json(hash.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_validate_hash", "kind", kind.to_string()))?; + let out = csv.validate_hash(&data, &hash); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_distance(port: i64, kind: u32, key1: FfiStr, key2: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let key1: veilid_core::CryptoKey = + veilid_core::deserialize_opt_json(key1.into_opt_string()).unwrap(); + let key2: veilid_core::CryptoKey = + veilid_core::deserialize_opt_json(key2.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_distance", "kind", kind.to_string()))?; + let out = csv.distance(&key1, &key2); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_sign(port: i64, kind: u32, key: FfiStr, secret: FfiStr, data: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let key: veilid_core::CryptoKey = + veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let secret: veilid_core::CryptoKey = + veilid_core::deserialize_opt_json(secret.into_opt_string()).unwrap(); + let data: Vec = data_encoding::BASE64URL_NOPAD + .decode( + data.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_sign", "kind", kind.to_string()))?; + let out = csv.sign(&key, &secret, &data)?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_verify(port: i64, kind: u32, key: FfiStr, data: FfiStr, signature: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let key: veilid_core::CryptoKey = + veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); + let data: Vec = data_encoding::BASE64URL_NOPAD + .decode( + data.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + let signature: veilid_core::Signature = + veilid_core::deserialize_opt_json(signature.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_verify", "kind", kind.to_string()))?; + let out = csv.verify(&key, &data, &signature)?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_aead_overhead(port: i64, kind: u32) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + DartIsolateWrapper::new(port).spawn_result(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_aead_overhead", "kind", kind.to_string()))?; + let out = csv.aead_overhead(); + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_decrypt_aead(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr, associated_data: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let body: Vec = data_encoding::BASE64URL_NOPAD + .decode( + body.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + + let nonce: veilid_core::Nonce = + veilid_core::deserialize_opt_json(nonce.into_opt_string()).unwrap(); + + let shared_secret: veilid_core::SharedSecret = + veilid_core::deserialize_opt_json(shared_secret.into_opt_string()).unwrap(); + + let associated_data: Option> = associated_data.into_opt_string().map(|s| data_encoding::BASE64URL_NOPAD.decode(s.as_bytes()).unwrap()); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_decrypt_aead", "kind", kind.to_string()))?; + let out = csv.decrypt_aead(&body, &nonce, &shared_secret, match &associated_data { + Some(ad) => Some(ad.as_slice()), + None => None + })?; + APIResult::Ok(out) + }); +} + +#[no_mangle] +pub extern "C" fn crypto_encrypt_aead(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr, associated_data: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let body: Vec = data_encoding::BASE64URL_NOPAD + .decode( + body.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + + let nonce: veilid_core::Nonce = + veilid_core::deserialize_opt_json(nonce.into_opt_string()).unwrap(); + + let shared_secret: veilid_core::SharedSecret = + veilid_core::deserialize_opt_json(shared_secret.into_opt_string()).unwrap(); + + let associated_data: Option> = associated_data.into_opt_string().map(|s| data_encoding::BASE64URL_NOPAD.decode(s.as_bytes()).unwrap()); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_encrypt_aead", "kind", kind.to_string()))?; + let out = csv.encrypt_aead(&body, &nonce, &shared_secret, match &associated_data { + Some(ad) => Some(ad.as_slice()), + None => None + })?; + APIResult::Ok(out) + }); +} + + + +#[no_mangle] +pub extern "C" fn crypto_crypt_no_auth(port: i64, kind: u32, body: FfiStr, nonce: FfiStr, shared_secret: FfiStr) { + let kind: veilid_core::CryptoKind = veilid_core::FourCC::from(kind); + + let mut body: Vec = data_encoding::BASE64URL_NOPAD + .decode( + body.into_opt_string() + .unwrap() + .as_bytes(), + ) + .unwrap(); + + let nonce: veilid_core::Nonce = + veilid_core::deserialize_opt_json(nonce.into_opt_string()).unwrap(); + + let shared_secret: veilid_core::SharedSecret = + veilid_core::deserialize_opt_json(shared_secret.into_opt_string()).unwrap(); + + DartIsolateWrapper::new(port).spawn_result_json(async move { + let veilid_api = get_veilid_api().await?; + let crypto = veilid_api.crypto()?; + let csv = crypto.get(kind).ok_or_else(|| veilid_core::VeilidAPIError::invalid_argument("crypto_crypt_no_auth", "kind", kind.to_string()))?; + csv.crypt_in_place_no_auth(&mut body, &nonce, &shared_secret); + APIResult::Ok(body) + }); +} + +#[no_mangle] +pub extern "C" fn now() -> u64 { + veilid_core::get_aligned_timestamp().as_u64() +} #[no_mangle] pub extern "C" fn debug(port: i64, command: FfiStr) {