MOD: code cleanup from ffi plugin to flutter rust bridge, codegen generate and flutter build macos GTG
This commit is contained in:
parent
9d8c2594d8
commit
a129711e4d
|
|
@ -18,7 +18,7 @@ This repository contains:
|
|||
|
||||
* A small Rust bridge crate referencing ``ccc_rust`` via a git tag
|
||||
* Generated ``flutter_rust_bridge`` bindings
|
||||
* A Flutter plugin scaffold (iOS / Android / macOS)
|
||||
* A Flutter plugin scaffold (iOS / Android / macOS / Linux / Windows)
|
||||
* A clean Dart API surface for applications
|
||||
|
||||
This plugin does **not** implement cryptography itself.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// The Android Gradle Plugin builds the native code with the Android NDK.
|
||||
|
||||
group = "com.example.ccc_cryptography"
|
||||
version = "1.0"
|
||||
group 'com.flutter_rust_bridge.ccc_cryptography'
|
||||
version '1.0'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
|
@ -11,7 +11,7 @@ buildscript {
|
|||
|
||||
dependencies {
|
||||
// The Android Gradle Plugin knows how to build native code with the NDK.
|
||||
classpath("com.android.tools.build:gradle:8.11.1")
|
||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -22,42 +22,35 @@ rootProject.allprojects {
|
|||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.android.library"
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
namespace = "com.example.ccc_cryptography"
|
||||
if (project.android.hasProperty("namespace")) {
|
||||
namespace 'com.flutter_rust_bridge.ccc_cryptography'
|
||||
}
|
||||
|
||||
// Bumping the plugin compileSdk version requires all clients of this plugin
|
||||
// Bumping the plugin compileSdkVersion requires all clients of this plugin
|
||||
// to bump the version in their app.
|
||||
compileSdk = 36
|
||||
compileSdkVersion 33
|
||||
|
||||
// Use the NDK version
|
||||
// declared in /android/app/build.gradle file of the Flutter project.
|
||||
// Replace it with a version number if this plugin requires a specific NDK version.
|
||||
// Replace it with a version number if this plugin requires a specfic NDK version.
|
||||
// (e.g. ndkVersion "23.1.7779620")
|
||||
ndkVersion = android.ndkVersion
|
||||
|
||||
// Invoke the shared CMake build with the Android Gradle Plugin.
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path = "../src/CMakeLists.txt"
|
||||
|
||||
// The default CMake version for the Android Gradle Plugin is 3.10.2.
|
||||
// https://developer.android.com/studio/projects/install-ndk#vanilla_cmake
|
||||
//
|
||||
// The Flutter tooling requires that developers have CMake 3.10 or later
|
||||
// installed. You should not increase this version, as doing so will cause
|
||||
// the plugin to fail to compile for some customers of the plugin.
|
||||
// version "3.10.2"
|
||||
}
|
||||
}
|
||||
ndkVersion android.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 24
|
||||
minSdkVersion 19
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "../cargokit/gradle/plugin.gradle"
|
||||
cargokit {
|
||||
manifestDir = "../rust"
|
||||
libname = "ccc_cryptography"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
|
||||
|
||||
FRB v2
|
||||
======
|
||||
With flutter_rust_bridge, the Rust dependency lives in Cargo.toml, not pubspec.yaml
|
||||
|
||||
FRB v2 ships with Cargokit — a build helper that hooks into each platform's build
|
||||
system (Gradle, Xcode, CMake) and compiles the Rust crate automatically at flutter build time.
|
||||
This means:
|
||||
* ccc_rust does not need a pubspec.yaml
|
||||
* ccc_rust stays a pure Rust crate
|
||||
* The current lum_ccc_rust entry in pubspec.yaml would be removed — it moves to rust/Cargo.toml
|
||||
|
||||
::
|
||||
|
||||
ccc_dart_plugin/
|
||||
├── pubspec.yaml ← NO reference to ccc_rust here
|
||||
├── rust/
|
||||
│ ├── Cargo.toml ← ccc_rust referenced HERE as a Rust crate dep
|
||||
│ └── src/api.rs ← thin wrappers calling ccc_rust
|
||||
|
||||
|
||||
ccc_rust
|
||||
========
|
||||
The Rust crypto library remains a pure Rust crate with no Flutter or FFI-specific code.
|
||||
Option 1: Build from source via Cargokit (recommended for development)
|
||||
* The Rust crate references ccc_rust via a git tag in Cargo.toml
|
||||
* Cargokit compiles the Rust code at build time for each platform
|
||||
* No precompiled binaries are needed
|
||||
|
||||
Option 2: Cargokit precompiled binaries via GitHub Releases (recommended for pub.dev)
|
||||
* The Rust crate is compiled into platform-specific binaries (staticlib for iOS/macOS, cdylib for Android)
|
||||
* Binaries are uploaded to GitHub Releases
|
||||
* Cargokit fetches the correct binary at build time based on the target platform
|
||||
* This allows pub.dev users to get native performance without needing Rust or a build environment
|
||||
|
||||
|
||||
Workflow
|
||||
--------
|
||||
* CI builds the Rust crate for all 5 platform targets
|
||||
* CI uploads the .so/.dylib/.dll/.framework to a GitHub Release tagged with the Cargo package hash
|
||||
* When consumers run flutter build, Cargokit downloads the precompiled binary instead of compiling
|
||||
* If no precompiled binary exists, it falls back to source build
|
||||
* Pros: Fast builds for consumers, no Rust toolchain needed, no repo bloat, built into FRB, single repo
|
||||
* Cons: Requires CI pipeline to build + upload binaries
|
||||
* Best for: pub.dev releases, distributing to teams without Rust installed
|
||||
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
CCC Dart Plugin — Architecture & Integration Guide
|
||||
====================================================
|
||||
|
||||
:Status: Milestone 2 (Planned)
|
||||
:Depends on: ``ccc_rust`` ≥ v0.1.0
|
||||
:Target: Flutter (iOS, Android, macOS)
|
||||
:Status: Milestone 2 (In Progress)
|
||||
:Depends on: ``ccc_rust`` ≥ v0.1.0 (ready)
|
||||
:Target: Flutter (iOS, Android, macOS, Linux, Windows)
|
||||
:Bridge: ``flutter_rust_bridge`` v2
|
||||
|
||||
Overview
|
||||
|
|
@ -23,7 +23,7 @@ This repository contains:
|
|||
|
||||
* A small Rust bridge crate referencing ``ccc_rust`` via a git tag
|
||||
* Generated ``flutter_rust_bridge`` bindings
|
||||
* A Flutter plugin scaffold (iOS / Android / macOS)
|
||||
* A Flutter plugin scaffold (iOS / Android / macOS / Linux / Windows)
|
||||
* A clean Dart API surface for applications
|
||||
|
||||
This plugin does **not** implement cryptography itself.
|
||||
|
|
@ -100,21 +100,25 @@ Repository Structure
|
|||
|
||||
ccc_dart_plugin/
|
||||
├── pubspec.yaml
|
||||
├── flutter_rust_bridge.yaml
|
||||
├── lib/
|
||||
│ ├── ccc_cryptography.dart # barrel export
|
||||
│ ├── ccc_crypto.dart
|
||||
│ ├── ccc_provider_catalog.dart
|
||||
│ ├── ccc_self_test.dart
|
||||
│ ├── ccc_exceptions.dart
|
||||
│ └── src/
|
||||
│ └── frb_generated.dart
|
||||
│ └── frb_generated.dart # auto-generated by FRB
|
||||
├── rust/
|
||||
│ ├── Cargo.toml
|
||||
│ └── src/
|
||||
│ ├── lib.rs
|
||||
│ └── api.rs
|
||||
├── flutter_rust_bridge.yaml
|
||||
│ └── api.rs # thin wrappers over ccc_rust
|
||||
├── ios/
|
||||
├── android/
|
||||
├── macos/
|
||||
├── linux/
|
||||
├── windows/
|
||||
└── test/
|
||||
└── roundtrip_test.dart
|
||||
|
||||
|
|
@ -128,7 +132,7 @@ Rust Bridge Crate
|
|||
.. code-block:: toml
|
||||
|
||||
[package]
|
||||
name = "ccc_dart_bridge"
|
||||
name = "ccc_cryptography"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
|
@ -228,13 +232,19 @@ Testing Requirements
|
|||
Before tagging ``v0.1.0`` of this plugin:
|
||||
|
||||
* Rust bridge builds for:
|
||||
- iOS (aarch64-apple-ios)
|
||||
- Android (arm64 + x86_64)
|
||||
- macOS (aarch64)
|
||||
* Flutter integration tests:
|
||||
- iOS (aarch64-apple-ios, aarch64-apple-ios-sim)
|
||||
- Android (aarch64-linux-android, x86_64-linux-android)
|
||||
- macOS (aarch64-apple-darwin, x86_64-apple-darwin)
|
||||
- Linux (x86_64-unknown-linux-gnu)
|
||||
- Windows (x86_64-pc-windows-msvc)
|
||||
* Unit tests (Dart-side, host platform):
|
||||
- AEAD roundtrip encrypt/decrypt
|
||||
- HKDF known-vector test
|
||||
- X25519 key agreement test
|
||||
- Provider catalog and self-test validation
|
||||
- Error handling / exception mapping
|
||||
* Flutter integration tests (on-device, all five platforms):
|
||||
- Full init → encrypt → decrypt flow
|
||||
* ``CccSelfTest.runAll()`` returns success
|
||||
* No Dart-side crypto logic present
|
||||
* No modification of ``ccc_rust`` source
|
||||
|
|
@ -296,3 +306,11 @@ Planned enhancements after Milestone 2:
|
|||
|
||||
----
|
||||
|
||||
Related Documents
|
||||
-----------------
|
||||
|
||||
* ``docs/milestone2_phases.rst`` — Phase-by-phase implementation
|
||||
tracker with task checklists and exit criteria.
|
||||
|
||||
----
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,574 @@
|
|||
CCC Dart Plugin — Milestone 2 Implementation Phases
|
||||
=====================================================
|
||||
|
||||
:Created: 2026-03-11
|
||||
:Last Updated: 2026-03-11
|
||||
:Status: In Progress
|
||||
:Depends on: ``ccc_rust`` ≥ v0.1.0 (ready)
|
||||
:Bridge: ``flutter_rust_bridge`` v2
|
||||
:Platforms: iOS, Android, macOS, Linux, Windows
|
||||
:Rust repo: ``ssh://git@10.0.5.109:j3g/lum_ccc_rust.git``
|
||||
:Local override: ``/Volumes/LUM/source/letusmsg_proj/app/lum_ccc_rust``
|
||||
|
||||
This document tracks the implementation phases for Milestone 2 —
|
||||
building the ``flutter_rust_bridge``-based Flutter plugin that exposes
|
||||
``ccc_rust`` cryptographic providers to Dart.
|
||||
|
||||
Related Documents
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ``docs/ccc_fplugin_architecture_design.rst`` — Architecture & integration guide
|
||||
* ``docs/ccc_rust_plan.rst`` — Master three-milestone architecture plan
|
||||
* ``docs/ccc_rust_plan_phases.rst`` — Phase tracking across all milestones
|
||||
* ``docs/ccc_rust_milestone2_session_state_OLD.rst`` — Earlier planning (superseded by this doc)
|
||||
|
||||
Preconditions (verified)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ``[x]`` Milestone 1 verification gate passed
|
||||
* ``[x]`` Conformance vectors passed in Rust workspace
|
||||
* ``[x]`` Rust target builds validated (iOS + Android)
|
||||
* ``[x]`` ``cargo audit`` — no known CVEs
|
||||
|
||||
----
|
||||
|
||||
Phase Overview
|
||||
--------------
|
||||
|
||||
====== ========================================== ========== ============
|
||||
Phase Title Status Depends on
|
||||
====== ========================================== ========== ============
|
||||
1 Project Restructure & FRB Setup Done —
|
||||
2 Rust Bridge Crate (DTOs + API) Not Started Phase 1
|
||||
3 Dart API Surface Not Started Phase 2
|
||||
4 Platform Build Verification Not Started Phase 3
|
||||
5 Unit Tests Not Started Phase 3
|
||||
6 Integration Tests & Polish Not Started Phase 4, 5
|
||||
====== ========================================== ========== ============
|
||||
|
||||
----
|
||||
|
||||
Phase 1 — Project Restructure & FRB Setup
|
||||
------------------------------------------
|
||||
|
||||
:Status: Done
|
||||
|
||||
**Goal:** Replace the placeholder C FFI scaffold with a
|
||||
``flutter_rust_bridge`` v2 project structure.
|
||||
|
||||
Tasks
|
||||
~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 60 15
|
||||
|
||||
* - #
|
||||
- Task
|
||||
- Status
|
||||
* - 1.1
|
||||
- Remove placeholder C source files (``src/ccc_cryptography.c``,
|
||||
``src/ccc_cryptography.h``)
|
||||
- ✅
|
||||
* - 1.2
|
||||
- Remove ``ffigen.yaml`` and generated bindings
|
||||
(``lib/ccc_cryptography_bindings_generated.dart``)
|
||||
- ✅
|
||||
* - 1.3
|
||||
- Create ``rust/`` directory with bridge crate scaffold
|
||||
(``Cargo.toml``, ``src/lib.rs``, ``src/api/``); FRB directory
|
||||
structure via ``flutter_rust_bridge_codegen integrate``;
|
||||
set ``crate-type = ["cdylib", "staticlib"]``
|
||||
- ✅
|
||||
* - 1.4
|
||||
- Add ``flutter_rust_bridge`` v2 dependency to ``rust/Cargo.toml``;
|
||||
reference ``ccc_rust`` crates via local path deps for dev
|
||||
(git deps commented for CI/release);
|
||||
crate name set to ``ccc_cryptography`` to match plugin
|
||||
- ✅
|
||||
* - 1.5
|
||||
- Create ``flutter_rust_bridge.yaml`` configuration
|
||||
(``rust_input: crate::api``, ``dart_output: lib/src/rust``)
|
||||
- ✅
|
||||
* - 1.6
|
||||
- Update ``pubspec.yaml``: replace ``ffigen`` with
|
||||
``flutter_rust_bridge``, add freezed, integration_test
|
||||
- ✅
|
||||
* - 1.7
|
||||
- Platform build configs generated by FRB integrate +
|
||||
Cargokit (CMakeLists, Podspecs, Gradle)
|
||||
- ✅
|
||||
* - 1.8
|
||||
- Run ``flutter_rust_bridge_codegen generate`` — bridge compiles;
|
||||
``flutter build macos`` succeeds (42.7 MB example app)
|
||||
- ✅
|
||||
|
||||
Exit Criteria
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* ``flutter_rust_bridge_codegen generate`` succeeds.
|
||||
* ``flutter build`` runs without errors on host (macOS).
|
||||
* No C FFI scaffolding remains.
|
||||
|
||||
----
|
||||
|
||||
Phase 2 — Rust Bridge Crate (DTOs + API)
|
||||
------------------------------------------
|
||||
|
||||
:Status: Not Started
|
||||
:Depends on: Phase 1
|
||||
|
||||
**Goal:** Implement DTOs and thin Rust wrappers in the bridge crate that
|
||||
expose all ``ccc_rust`` provider functionality across the FRB bridge.
|
||||
|
||||
The bridge crate lives at ``rust/`` and must not contain any cryptographic
|
||||
logic — only type conversions and delegation to ``ccc_rust`` providers.
|
||||
|
||||
DTOs (``rust/src/dto.rs``)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Bridge-visible data transfer objects with ``From<core type>`` impls:
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 60 15
|
||||
|
||||
* - #
|
||||
- Task
|
||||
- Status
|
||||
* - 2.1
|
||||
- ``CapabilitiesDto`` — maps from ``ProviderCapabilities``
|
||||
(provider name, algorithm availability, efficiency/reliability
|
||||
scores)
|
||||
- ☐
|
||||
* - 2.2
|
||||
- ``KemKeyPairDto`` — maps from ``KemKeyPair``
|
||||
(public_key, private_key as ``Vec<u8>``)
|
||||
- ☐
|
||||
* - 2.3
|
||||
- ``KemEncapDto`` — maps from KEM encapsulation result
|
||||
(ciphertext, shared_secret)
|
||||
- ☐
|
||||
* - 2.4
|
||||
- ``SelfTestDto`` — maps from ``SelfTestReport``
|
||||
(overall pass/fail, per-algorithm results)
|
||||
- ☐
|
||||
* - 2.5
|
||||
- ``AlgoTestResultDto`` — maps from ``AlgoTestResult``
|
||||
(algorithm ID, pass/fail, diagnostic message)
|
||||
- ☐
|
||||
|
||||
Bridge API (``rust/src/api.rs``)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 60 15
|
||||
|
||||
* - #
|
||||
- Task
|
||||
- Status
|
||||
* - 2.6
|
||||
- ``ccc_init()`` — register WolfSslProvider, run capability probe
|
||||
- ☐
|
||||
* - 2.7
|
||||
- ``ccc_list_providers()`` — return registered provider names
|
||||
- ☐
|
||||
* - 2.8
|
||||
- ``ccc_capabilities()`` / ``ccc_available_algorithms()``
|
||||
— return ``CapabilitiesDto`` for a provider
|
||||
- ☐
|
||||
* - 2.9
|
||||
- ``ccc_aead_encrypt(algorithm, key, nonce, plaintext, aad)``
|
||||
— thin wrapper over provider AEAD encrypt
|
||||
- ☐
|
||||
* - 2.10
|
||||
- ``ccc_aead_decrypt(algorithm, key, nonce, ciphertext, aad)``
|
||||
— thin wrapper over provider AEAD decrypt
|
||||
- ☐
|
||||
* - 2.11
|
||||
- ``ccc_kdf_derive(algorithm, ikm, salt, info, len)``
|
||||
— thin wrapper over provider KDF
|
||||
- ☐
|
||||
* - 2.12
|
||||
- ``ccc_mac_compute(algorithm, key, data)``
|
||||
— thin wrapper over provider MAC compute
|
||||
- ☐
|
||||
* - 2.13
|
||||
- ``ccc_mac_verify(algorithm, key, data, mac)``
|
||||
— thin wrapper over provider MAC verify
|
||||
- ☐
|
||||
* - 2.14
|
||||
- ``ccc_hash(algorithm, data)``
|
||||
— thin wrapper over provider hash
|
||||
- ☐
|
||||
* - 2.15
|
||||
- ``ccc_kem_generate_keypair(algorithm)``
|
||||
— return ``KemKeyPairDto``
|
||||
- ☐
|
||||
* - 2.16
|
||||
- ``ccc_kem_encapsulate(algorithm, public_key)``
|
||||
— return ``KemEncapDto``
|
||||
- ☐
|
||||
* - 2.17
|
||||
- ``ccc_kem_decapsulate(algorithm, private_key, ciphertext)``
|
||||
— return shared secret
|
||||
- ☐
|
||||
* - 2.18
|
||||
- ``ccc_self_test()`` — return ``SelfTestDto``
|
||||
- ☐
|
||||
* - 2.19
|
||||
- Define bridge-visible error enum mapping ``CryptoError``
|
||||
variants to structured types (``UnsupportedAlgorithm``,
|
||||
``InvalidKey``, ``InvalidNonce``, ``AuthenticationFailed``,
|
||||
``InternalError``)
|
||||
- ☐
|
||||
* - 2.20
|
||||
- Run ``flutter_rust_bridge_codegen generate`` — verify all
|
||||
wrappers produce valid Dart bindings
|
||||
- ☐
|
||||
|
||||
DTO ↔ Rust Type Mapping
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
======================== =================================== ========================
|
||||
Bridge DTO Rust Core Type Direction
|
||||
======================== =================================== ========================
|
||||
``CapabilitiesDto`` ``ProviderCapabilities`` Rust → Dart
|
||||
``KemKeyPairDto`` ``KemKeyPair`` Rust → Dart
|
||||
``KemEncapDto`` (ciphertext, shared_secret) Rust → Dart
|
||||
``SelfTestDto`` ``SelfTestReport`` Rust → Dart
|
||||
``AlgoTestResultDto`` ``AlgoTestResult`` Rust → Dart
|
||||
``CryptoError`` enum ``CryptoError`` Rust → Dart exception
|
||||
======================== =================================== ========================
|
||||
|
||||
Exit Criteria
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* All DTOs defined with ``From<>`` impls.
|
||||
* All 13 bridge entry points exist in ``api.rs``.
|
||||
* Codegen produces Dart bindings without warnings.
|
||||
* Rust crate compiles with ``ccc_rust`` linked.
|
||||
|
||||
----
|
||||
|
||||
Phase 3 — Dart API Surface
|
||||
----------------------------
|
||||
|
||||
:Status: Not Started
|
||||
:Depends on: Phase 2
|
||||
|
||||
**Goal:** Build the clean Dart API layer that application code will
|
||||
consume, wired to the FRB-generated bindings.
|
||||
|
||||
Tasks
|
||||
~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 60 15
|
||||
|
||||
* - #
|
||||
- Task
|
||||
- Status
|
||||
* - 3.1
|
||||
- Create ``lib/ccc_crypto.dart`` — primary entry point class
|
||||
``CccCrypto`` with all public methods:
|
||||
``cccInit``, ``listProviders``, ``getCapabilities``,
|
||||
``encryptAead``, ``decryptAead``, ``deriveKey``,
|
||||
``computeMac``, ``verifyMac``, ``hash``,
|
||||
``kemGenerateKeypair``, ``kemEncapsulate``, ``kemDecapsulate``,
|
||||
``runSelfTest``
|
||||
- ☐
|
||||
* - 3.2
|
||||
- Create ``lib/ccc_provider_catalog.dart`` — ``CccProviderCatalog``
|
||||
(provider name, algorithms, efficiency/reliability scores)
|
||||
- ☐
|
||||
* - 3.3
|
||||
- Create ``lib/ccc_self_test.dart`` — ``CccSelfTestResult``
|
||||
(per-algorithm pass/fail, overall status, diagnostics)
|
||||
- ☐
|
||||
* - 3.4
|
||||
- Create ``lib/ccc_exceptions.dart`` — structured exception
|
||||
classes (``CccUnsupportedAlgorithm``, ``CccInvalidKey``,
|
||||
``CccInvalidNonce``, ``CccAuthenticationFailed``,
|
||||
``CccInternalError``)
|
||||
- ☐
|
||||
* - 3.5
|
||||
- Create ``lib/ccc_algorithm_ids.dart`` — algorithm ID constants
|
||||
matching Rust enum discriminants 1-to-1 (values from
|
||||
``cipher_constants.dart``); no remapping
|
||||
- ☐
|
||||
* - 3.6
|
||||
- Wire all Dart API methods to FRB-generated bindings
|
||||
- ☐
|
||||
* - 3.7
|
||||
- Create barrel export file ``lib/ccc_cryptography.dart``
|
||||
re-exporting the public API
|
||||
- ☐
|
||||
* - 3.8
|
||||
- Remove old placeholder Dart code (``sum``, ``sumAsync``)
|
||||
- ☐
|
||||
|
||||
Exit Criteria
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* ``dart analyze`` reports no errors or warnings.
|
||||
* Public API matches the contract in the architecture design doc.
|
||||
* No crypto logic exists in Dart — orchestration only.
|
||||
|
||||
----
|
||||
|
||||
Phase 4 — Platform Build Verification
|
||||
---------------------------------------
|
||||
|
||||
:Status: Not Started
|
||||
:Depends on: Phase 3
|
||||
|
||||
**Goal:** Verify the Rust bridge crate cross-compiles and links
|
||||
correctly on all five target platforms.
|
||||
|
||||
Tasks
|
||||
~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 60 15
|
||||
|
||||
* - #
|
||||
- Task
|
||||
- Status
|
||||
* - 4.1
|
||||
- Build for **iOS** (``aarch64-apple-ios``,
|
||||
``aarch64-apple-ios-sim``)
|
||||
- ☐
|
||||
* - 4.2
|
||||
- Build for **Android** (``aarch64-linux-android``,
|
||||
``x86_64-linux-android``)
|
||||
- ☐
|
||||
* - 4.3
|
||||
- Build for **macOS** (``aarch64-apple-darwin``,
|
||||
``x86_64-apple-darwin``)
|
||||
- ☐
|
||||
* - 4.4
|
||||
- Build for **Linux** (``x86_64-unknown-linux-gnu``)
|
||||
- ☐
|
||||
* - 4.5
|
||||
- Build for **Windows** (``x86_64-pc-windows-msvc``)
|
||||
- ☐
|
||||
* - 4.6
|
||||
- Fix any platform-specific linker or NDK issues
|
||||
- ☐
|
||||
* - 4.7
|
||||
- Verify ``flutter run`` launches on at least one
|
||||
physical/emulated device per platform
|
||||
- ☐
|
||||
|
||||
Exit Criteria
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* ``flutter build`` succeeds for all five platforms.
|
||||
* Native library is bundled correctly in each platform's output.
|
||||
|
||||
----
|
||||
|
||||
Phase 5 — Unit Tests
|
||||
---------------------
|
||||
|
||||
:Status: Not Started
|
||||
:Depends on: Phase 3
|
||||
|
||||
**Goal:** Verify correctness of the bridge and Dart API via
|
||||
Dart-side unit tests.
|
||||
|
||||
Tasks
|
||||
~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 60 15
|
||||
|
||||
* - #
|
||||
- Task
|
||||
- Status
|
||||
* - 5.1
|
||||
- AEAD roundtrip test — encrypt then decrypt 1 KB
|
||||
(AES-256-GCM), verify plaintext equality
|
||||
- ☐
|
||||
* - 5.2
|
||||
- AEAD roundtrip test — encrypt then decrypt 1 KB
|
||||
(ChaCha20-Poly1305)
|
||||
- ☐
|
||||
* - 5.3
|
||||
- AEAD tamper test — modify ciphertext, verify
|
||||
``CccAuthenticationFailed`` is thrown
|
||||
- ☐
|
||||
* - 5.4
|
||||
- KDF known-vector test — HKDF-SHA256 output compared against
|
||||
RFC 5869 test vectors
|
||||
- ☐
|
||||
* - 5.5
|
||||
- MAC roundtrip test — ``computeMac`` then ``verifyMac``
|
||||
(HMAC-SHA256), verify returns true
|
||||
- ☐
|
||||
* - 5.6
|
||||
- MAC tamper test — modify data after MAC, verify returns false
|
||||
- ☐
|
||||
* - 5.7
|
||||
- Hash known-vector test — compare output against known
|
||||
SHA-256 / SHA-384 / SHA-512 digests
|
||||
- ☐
|
||||
* - 5.8
|
||||
- KEM roundtrip test — ``kemGenerateKeypair``,
|
||||
``kemEncapsulate``, ``kemDecapsulate`` (X25519); verify
|
||||
shared secrets match
|
||||
- ☐
|
||||
* - 5.9
|
||||
- KEM roundtrip test — X448 keygen/encap/decap flow
|
||||
- ☐
|
||||
* - 5.10
|
||||
- Provider catalog test — verify ``listProviders()`` returns
|
||||
non-empty list, ``getCapabilities()`` returns per-algorithm
|
||||
availability and scores
|
||||
- ☐
|
||||
* - 5.11
|
||||
- Self-test validation — ``runSelfTest()`` returns overall pass
|
||||
with per-algorithm results
|
||||
- ☐
|
||||
* - 5.12
|
||||
- Error handling tests — verify each ``CccException`` subtype
|
||||
is thrown for the corresponding error condition
|
||||
(unsupported algorithm, invalid key, invalid nonce)
|
||||
- ☐
|
||||
* - 5.13
|
||||
- Algorithm ID mapping test — verify Dart constants match
|
||||
Rust enum discriminants (1-to-1, no drift)
|
||||
- ☐
|
||||
|
||||
Exit Criteria
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* All unit tests pass on host platform (macOS).
|
||||
* No Dart-side crypto logic introduced by tests.
|
||||
|
||||
----
|
||||
|
||||
Phase 6 — Integration Tests & Polish
|
||||
--------------------------------------
|
||||
|
||||
:Status: Not Started
|
||||
:Depends on: Phase 4, Phase 5
|
||||
|
||||
**Goal:** End-to-end validation on real devices/simulators, example
|
||||
app update, documentation, and release preparation.
|
||||
|
||||
Tasks
|
||||
~~~~~
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 5 60 15
|
||||
|
||||
* - #
|
||||
- Task
|
||||
- Status
|
||||
* - 6.1
|
||||
- Write Flutter integration tests (``integration_test/``) that
|
||||
exercise the full init → encrypt → decrypt flow on-device
|
||||
- ☐
|
||||
* - 6.2
|
||||
- Integration test: KEM keygen → encap → decap roundtrip
|
||||
- ☐
|
||||
* - 6.3
|
||||
- Integration test: self-test API returns all-pass
|
||||
- ☐
|
||||
* - 6.4
|
||||
- Run integration tests on iOS simulator
|
||||
- ☐
|
||||
* - 6.5
|
||||
- Run integration tests on Android emulator
|
||||
- ☐
|
||||
* - 6.6
|
||||
- Run integration tests on macOS
|
||||
- ☐
|
||||
* - 6.7
|
||||
- Run integration tests on Linux
|
||||
- ☐
|
||||
* - 6.8
|
||||
- Run integration tests on Windows
|
||||
- ☐
|
||||
* - 6.9
|
||||
- Update example app (``example/``) — replace ``sum`` demo with
|
||||
real crypto demo (encrypt/decrypt, provider listing, self-test)
|
||||
- ☐
|
||||
* - 6.10
|
||||
- Update ``CHANGELOG.md`` for v0.1.0
|
||||
- ☐
|
||||
* - 6.11
|
||||
- Final review — confirm no Dart crypto logic, no ``ccc_rust``
|
||||
source modifications, all tests green
|
||||
- ☐
|
||||
* - 6.12
|
||||
- Tag ``v0.1.0`` of the plugin
|
||||
- ☐
|
||||
|
||||
Exit Criteria
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
* Integration tests pass on all five platforms.
|
||||
* Example app demonstrates real cryptographic operations.
|
||||
* ``CHANGELOG.md`` is updated.
|
||||
* Repository tagged ``v0.1.0``.
|
||||
|
||||
----
|
||||
|
||||
Milestone 2 Verification Gate
|
||||
------------------------------
|
||||
|
||||
*All items must be checked before the* ``v0.1.0`` *tag is cut.*
|
||||
|
||||
* ``[ ]`` FRB bridge API compiles and loads in Flutter plugin
|
||||
* ``[ ]`` Generated Dart bindings are committed and reproducible
|
||||
* ``[ ]`` All unit tests pass on host platform (macOS)
|
||||
* ``[ ]`` ``flutter build ios`` succeeds
|
||||
* ``[ ]`` ``flutter build apk`` succeeds
|
||||
* ``[ ]`` ``flutter build macos`` succeeds
|
||||
* ``[ ]`` ``flutter build linux`` succeeds
|
||||
* ``[ ]`` ``flutter build windows`` succeeds
|
||||
* ``[ ]`` Integration tests pass on iOS simulator
|
||||
* ``[ ]`` Integration tests pass on Android emulator/device
|
||||
* ``[ ]`` Integration tests pass on macOS
|
||||
* ``[ ]`` Integration tests pass on Linux
|
||||
* ``[ ]`` Integration tests pass on Windows
|
||||
* ``[ ]`` No Dart-side crypto logic present
|
||||
* ``[ ]`` No modification of ``ccc_rust`` source
|
||||
* ``[ ]`` ``ccc_rust`` dependency pinned to exact commit/tag
|
||||
* ``[ ]`` Plugin package tagged ``v0.1.0``
|
||||
|
||||
----
|
||||
|
||||
Milestone 3 Handoff Checklist
|
||||
------------------------------
|
||||
|
||||
Before handing off to the LetUsMsg app team:
|
||||
|
||||
☐ All Phase 1–6 exit criteria met
|
||||
☐ Milestone 2 Verification Gate passed
|
||||
☐ ``CccCrypto`` public API is stable and documented
|
||||
☐ No floating dependencies (all git refs pinned)
|
||||
☐ Self-test passes on all platforms
|
||||
☐ Example app runs on all platforms
|
||||
☐ No raw private keys exposed to Dart
|
||||
☐ ``pubspec.yaml`` is publishable (or git-installable)
|
||||
|
||||
The LetUsMsg app will:
|
||||
|
||||
* Add this plugin via ``pubspec.yaml``
|
||||
* Call ``CccCrypto.cccInit()`` at startup
|
||||
* Replace existing crypto stubs with plugin calls
|
||||
* Populate ``CccProviderCatalog`` from runtime capabilities
|
||||
* Surface ``CccSelfTest.runAll()`` in debug UI
|
||||
|
||||
No Rust changes and no bridge changes are permitted during Milestone 3.
|
||||
|
||||
----
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
=====================================================
|
||||
CCC Rust Milestone 2 — Session State (Planning)
|
||||
=====================================================
|
||||
|
||||
:Status: Not started
|
||||
:Date: 2026-02-26
|
||||
:Repository target: ``ccc_cryptography`` (plugin repo)
|
||||
:Depends on: ``ccc_rust`` Milestone 1 complete
|
||||
|
||||
Related Documents
|
||||
=================
|
||||
|
||||
* Milestone 1 completion record:
|
||||
``docs/ccc_rust_milestone1.rst``
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This document tracks Milestone 2 execution state for Flutter plugin + bridge work.
|
||||
Milestone 2 begins with Milestone 1 already verified and complete.
|
||||
|
||||
Current Gate Preconditions
|
||||
==========================
|
||||
|
||||
* ``[x]`` Milestone 1 verification gate passed.
|
||||
* ``[x]`` Conformance vectors passed in Rust workspace.
|
||||
* ``[x]`` Rust target builds validated (iOS + Android).
|
||||
|
||||
Milestone 2 Work Checklist
|
||||
==========================
|
||||
|
||||
Phase 1 — Repository + Scaffold
|
||||
-------------------------------
|
||||
|
||||
* ``[ ]`` Create/confirm ``ccc_cryptography`` repository and branch strategy.
|
||||
* ``[ ]`` Create Flutter plugin scaffold (``pubspec.yaml``, ``ios/``, ``android/``, ``macos/``).
|
||||
* ``[ ]`` Add Rust bridge crate with ``crate-type = ["cdylib", "staticlib"]``.
|
||||
* ``[ ]`` Wire dependency on ``ccc_rust`` pinned tag/revision.
|
||||
|
||||
Phase 2 — Bridge API Surface
|
||||
----------------------------
|
||||
|
||||
* ``[ ]`` Define DTOs:
|
||||
|
||||
* ``CapabilitiesDto``
|
||||
* ``KemKeyPairDto``
|
||||
* ``KemEncapDto``
|
||||
* ``SelfTestDto``
|
||||
* ``AlgoTestResultDto``
|
||||
|
||||
* ``[ ]`` Implement bridge entry points:
|
||||
|
||||
* ``ccc_init``
|
||||
* ``ccc_list_providers``
|
||||
* ``ccc_capabilities`` / ``ccc_available_algorithms``
|
||||
* ``ccc_aead_encrypt`` / ``ccc_aead_decrypt``
|
||||
* ``ccc_kdf_derive``
|
||||
* ``ccc_mac_compute`` / ``ccc_mac_verify``
|
||||
* ``ccc_hash``
|
||||
* ``ccc_kem_generate_keypair``
|
||||
* ``ccc_kem_encapsulate`` / ``ccc_kem_decapsulate``
|
||||
* ``ccc_self_test``
|
||||
|
||||
Phase 3 — FRB Codegen + Build Integration
|
||||
-----------------------------------------
|
||||
|
||||
* ``[ ]`` Add ``flutter_rust_bridge`` configuration + codegen scripts.
|
||||
* ``[ ]`` Run FRB codegen and commit generated artifacts.
|
||||
* ``[ ]`` Verify plugin compiles for iOS.
|
||||
* ``[ ]`` Verify plugin compiles for Android.
|
||||
* ``[ ]`` Verify plugin compiles for macOS.
|
||||
|
||||
Phase 4 — Dart API Layer
|
||||
------------------------
|
||||
|
||||
* ``[ ]`` Implement ``CccCrypto`` service API wrapper.
|
||||
* ``[ ]`` Implement ``CccSelfTest`` wrapper.
|
||||
* ``[ ]`` Implement runtime ``CccProviderCatalog`` population.
|
||||
* ``[ ]`` Ensure algorithm ID mapping remains 1:1 with Rust discriminants.
|
||||
|
||||
Phase 5 — Integration + Validation
|
||||
----------------------------------
|
||||
|
||||
* ``[ ]`` Add integration tests for AEAD roundtrip (at least AES-GCM and ChaCha20).
|
||||
* ``[ ]`` Add integration tests for KEM keygen/encap/decap flow.
|
||||
* ``[ ]`` Add integration tests for self-test API.
|
||||
* ``[ ]`` Run on iOS simulator.
|
||||
* ``[ ]`` Run on Android emulator/device.
|
||||
|
||||
Milestone 2 TODO Queue
|
||||
======================
|
||||
|
||||
Immediate TODOs (next session)
|
||||
------------------------------
|
||||
|
||||
* ``[ ]`` Decide exact Milestone 2 repository location/URL and baseline branch.
|
||||
* ``[ ]`` Pin ``ccc_rust`` dependency to a reproducible reference (tag or commit hash).
|
||||
* ``[ ]`` Define FRB module layout and generated file commit policy.
|
||||
* ``[ ]`` Draft DTO type mapping table (Rust type -> bridge DTO -> Dart model).
|
||||
|
||||
Backlog TODOs
|
||||
-------------
|
||||
|
||||
* ``[ ]`` Add CI job matrix for iOS/macOS/Android plugin builds.
|
||||
* ``[ ]`` Add versioning/release policy for plugin package.
|
||||
* ``[ ]`` Add troubleshooting notes for NDK/Xcode toolchains.
|
||||
|
||||
Milestone 2 Verification Gate
|
||||
=============================
|
||||
|
||||
All of the following must pass before declaring Milestone 2 complete:
|
||||
|
||||
* ``[ ]`` FRB bridge API compiles and loads in Flutter plugin.
|
||||
* ``[ ]`` Generated Dart bindings are committed and reproducible.
|
||||
* ``[ ]`` ``flutter build ios`` succeeds.
|
||||
* ``[ ]`` ``flutter build apk`` succeeds.
|
||||
* ``[ ]`` ``flutter build macos`` succeeds.
|
||||
* ``[ ]`` Integration test suite passes on iOS simulator.
|
||||
* ``[ ]`` Integration test suite passes on Android emulator/device.
|
||||
* ``[ ]`` Plugin package is tagged/released at ``v0.1.0`` (or agreed target version).
|
||||
|
||||
Notes
|
||||
=====
|
||||
|
||||
* Milestone 2 is the first place where ``flutter_rust_bridge`` is allowed.
|
||||
* Milestone 1 Rust workspace remains bridge-free and should not be modified
|
||||
for Dart/plugin scaffolding.
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
===============================================
|
||||
CCC Rust Crypto Provider — Architecture Plan
|
||||
===============================================
|
||||
|
||||
:Status: Approved
|
||||
:Date: 2026-02-24
|
||||
:Author: Engineering
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
This document describes the architecture for the **CCC Rust Crypto Provider**,
|
||||
the first of three milestones in delivering hardware-grade cryptography to the
|
||||
LetUsMsg application.
|
||||
|
||||
The guiding constraint is *clean separation*: each milestone is a distinct,
|
||||
independently testable artifact with no forbidden upward dependencies.
|
||||
|
||||
----
|
||||
|
||||
Three-Milestone Strategy
|
||||
------------------------
|
||||
|
||||
============= =================================== ========================== ===========================
|
||||
Milestone Repository What ships Depends on
|
||||
============= =================================== ========================== ===========================
|
||||
**1 (this)** ``ccc_rust`` Pure Rust crypto library wolfSSL (vendored)
|
||||
**2** ``ccc_dart_plugin`` Flutter plugin + Dart API ``ccc_rust`` (git/semver)
|
||||
**3** ``letusmsg`` (existing app) App integration ``ccc_dart_plugin`` package
|
||||
============= =================================== ========================== ===========================
|
||||
|
||||
Milestone 1 is complete and independently verified *before* any bridge or Dart
|
||||
code is written. Milestone 2 owns the ``flutter_rust_bridge`` dependency and
|
||||
all generated Dart bindings. Milestone 3 makes no Rust changes; it consumes
|
||||
only the published Dart package.
|
||||
|
||||
----
|
||||
|
||||
Milestone 1 — ``ccc_rust`` Scope (this repository)
|
||||
|
||||
**Goal**: a fully tested, provider-agnostic Rust crypto library.
|
||||
|
||||
**Hard boundaries** — this repo must never contain:
|
||||
|
||||
* ``flutter_rust_bridge`` or any Flutter/Dart dependency
|
||||
* Generated Dart files (``frb_generated.rs``, ``*.dart``)
|
||||
* ``flutter_rust_bridge.yaml``
|
||||
* Any platform plugin scaffold (``ios/``, ``android/``, ``macos/``)
|
||||
|
||||
Guiding Principles
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Every provider reports its own capabilities at runtime — no compile-time
|
||||
hard-coding of ``available: true/false``.
|
||||
2. Algorithm IDs in Rust map 1-to-1 to the integer constants in
|
||||
``cipher_constants.dart`` — zero Dart changes needed when wiring up.
|
||||
3. Key material is zeroed on drop (``zeroize`` crate) everywhere.
|
||||
4. A conformance test suite validates NIST/RFC vectors for every algorithm
|
||||
before any provider is marked ``available``.
|
||||
5. The library has no runtime dependency on Flutter; it is consumable by any
|
||||
FFI host (Flutter plugin, Python tests, CLI tools).
|
||||
|
||||
Repository Layout (Milestone 1 — this repo)
|
||||
|
||||
::
|
||||
|
||||
ccc_rust/
|
||||
├── Cargo.toml ← workspace manifest (3 members, no bridge)
|
||||
├── rust-toolchain.toml ← pinned stable toolchain
|
||||
├── .cargo/
|
||||
│ └── config.toml ← cross-compile target aliases
|
||||
├── vendors/
|
||||
│ ├── README.md ← submodule pin rationale + upgrade notes
|
||||
│ └── wolfssl/ ← git submodule (wolfSSL/wolfssl @ v5.7.2-stable)
|
||||
├── crates/
|
||||
│ ├── ccc-crypto-core/ ← shared traits, enums, registry
|
||||
│ │ ├── Cargo.toml
|
||||
│ │ └── src/
|
||||
│ │ ├── lib.rs
|
||||
│ │ ├── algorithms.rs ← algorithm enums (values == cipher_constants.dart)
|
||||
│ │ ├── capabilities.rs ← AlgorithmCapability, ProviderCapabilities
|
||||
│ │ ├── error.rs ← CryptoError enum
|
||||
│ │ ├── provider.rs ← CryptoProvider umbrella trait
|
||||
│ │ ├── registry.rs ← ProviderRegistry (OnceLock<Mutex<...>>)
|
||||
│ │ └── types.rs ← KemKeyPair, SelfTestReport, BenchmarkReport
|
||||
│ └── ccc-crypto-wolfssl/ ← wolfSSL provider implementation
|
||||
│ ├── Cargo.toml
|
||||
│ └── src/
|
||||
│ ├── lib.rs
|
||||
│ ├── aead.rs ← AES-256-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305
|
||||
│ ├── kdf.rs ← HKDF-SHA256/384/512, Argon2id, BLAKE2b-KDF
|
||||
│ ├── mac.rs ← HMAC-SHA256/384/512, BLAKE2b-MAC
|
||||
│ ├── hash.rs ← SHA-256/384/512, SHA3-256/512, BLAKE2b-512
|
||||
│ ├── kem.rs ← X25519, X448 (ML-KEM deferred Phase 5)
|
||||
│ ├── capabilities.rs ← probe-at-startup + benchmark()
|
||||
│ └── provider.rs ← WolfSslProvider: CryptoProvider impl
|
||||
└── tests/
|
||||
└── conformance/
|
||||
├── Cargo.toml
|
||||
└── src/
|
||||
└── main.rs ← NIST/RFC vectors for all algorithms
|
||||
|
||||
Step 1 — Cargo Workspace Scaffold
|
||||
|
||||
``Cargo.toml``::
|
||||
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"crates/ccc-crypto-core",
|
||||
"crates/ccc-crypto-wolfssl",
|
||||
"tests/conformance",
|
||||
]
|
||||
|
||||
``rust-toolchain.toml``::
|
||||
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
|
||||
``.cargo/config.toml``::
|
||||
|
||||
[alias]
|
||||
build-ios = "build --target aarch64-apple-ios"
|
||||
build-android-arm64 = "build --target aarch64-linux-android"
|
||||
build-android-x64 = "build --target x86_64-linux-android"
|
||||
build-macos = "build --target aarch64-apple-darwin"
|
||||
|
||||
Step 2 — ``ccc-crypto-core`` Trait Crate
|
||||
|
||||
Algorithm Enumerations
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
All discriminant values match the integer constants in ``cipher_constants.dart``
|
||||
exactly, so the Dart cipher-sequencing logic requires zero changes.
|
||||
|
||||
=================== =========================================================
|
||||
Enum Variants → value
|
||||
=================== =========================================================
|
||||
``AeadAlgorithm`` AesGcm256=12, ChaCha20Poly1305=13, XChaCha20Poly1305=14,
|
||||
Ascon128a=15
|
||||
``KdfAlgorithm`` Sha256=1, Sha384=2, Sha512=3, Blake2b512=4
|
||||
``MacAlgorithm`` HmacSha256=30, HmacSha512=32, Blake2bMac=33
|
||||
``HashAlgorithm`` Sha256=40, Sha384=41, Sha512=42, Blake2b512=43, Sha3_256=44
|
||||
``KemAlgorithm`` X25519=50, X448=51, MlKem768=52, MlKem1024=53,
|
||||
ClassicMcEliece=54
|
||||
=================== =========================================================
|
||||
|
||||
Key Structs
|
||||
~~~~~~~~~~~
|
||||
|
||||
``AlgorithmCapability``::
|
||||
|
||||
available: bool
|
||||
deterministic_io: bool
|
||||
efficiency_score: u8 // populated by WolfSslProvider::benchmark()
|
||||
reliability_score: u8 // populated by WolfSslProvider::self_test()
|
||||
|
||||
``ProviderCapabilities``::
|
||||
|
||||
provider_name: &'static str
|
||||
aead: HashMap<AeadAlgorithm, AlgorithmCapability>
|
||||
kdf: HashMap<KdfAlgorithm, AlgorithmCapability>
|
||||
mac: HashMap<MacAlgorithm, AlgorithmCapability>
|
||||
hash: HashMap<HashAlgorithm, AlgorithmCapability>
|
||||
kem: HashMap<KemAlgorithm, AlgorithmCapability>
|
||||
|
||||
``KemKeyPair``::
|
||||
|
||||
public_key: Zeroizing<Vec<u8>>
|
||||
private_key: Zeroizing<Vec<u8>>
|
||||
|
||||
``CryptoError``::
|
||||
|
||||
UnsupportedAlgorithm(String)
|
||||
InvalidKey(String)
|
||||
InvalidNonce(String)
|
||||
AuthenticationFailed
|
||||
InternalError(String)
|
||||
|
||||
Provider Traits
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: rust
|
||||
|
||||
pub trait AeadProvider {
|
||||
fn encrypt_aead(
|
||||
&self, algo: AeadAlgorithm,
|
||||
key: &[u8], nonce: &[u8],
|
||||
plaintext: &[u8], aad: &[u8],
|
||||
) -> Result<Vec<u8>, CryptoError>;
|
||||
fn decrypt_aead(
|
||||
&self, algo: AeadAlgorithm,
|
||||
key: &[u8], nonce: &[u8],
|
||||
ciphertext: &[u8], aad: &[u8],
|
||||
) -> Result<Vec<u8>, CryptoError>;
|
||||
}
|
||||
|
||||
pub trait KdfProvider {
|
||||
fn derive_key(
|
||||
&self, algo: KdfAlgorithm,
|
||||
ikm: &[u8], salt: &[u8], info: &[u8], length: usize,
|
||||
) -> Result<Zeroizing<Vec<u8>>, CryptoError>;
|
||||
}
|
||||
|
||||
pub trait MacProvider {
|
||||
fn compute_mac(
|
||||
&self, algo: MacAlgorithm, key: &[u8], data: &[u8],
|
||||
) -> Result<Vec<u8>, CryptoError>;
|
||||
fn verify_mac(
|
||||
&self, algo: MacAlgorithm, key: &[u8],
|
||||
data: &[u8], mac: &[u8],
|
||||
) -> Result<bool, CryptoError>;
|
||||
}
|
||||
|
||||
pub trait HashProvider {
|
||||
fn hash(
|
||||
&self, algo: HashAlgorithm, data: &[u8],
|
||||
) -> Result<Vec<u8>, CryptoError>;
|
||||
}
|
||||
|
||||
pub trait KemProvider {
|
||||
fn generate_keypair(
|
||||
&self, algo: KemAlgorithm,
|
||||
) -> Result<KemKeyPair, CryptoError>;
|
||||
fn encapsulate(
|
||||
&self, algo: KemAlgorithm, public_key: &[u8],
|
||||
) -> Result<(Vec<u8>, Zeroizing<Vec<u8>>), CryptoError>;
|
||||
fn decapsulate(
|
||||
&self, algo: KemAlgorithm,
|
||||
private_key: &[u8], ciphertext: &[u8],
|
||||
) -> Result<Zeroizing<Vec<u8>>, CryptoError>;
|
||||
}
|
||||
|
||||
pub trait CryptoProvider:
|
||||
AeadProvider + KdfProvider + MacProvider + HashProvider + Send + Sync
|
||||
{
|
||||
fn provider_name(&self) -> &'static str;
|
||||
fn capabilities(&self) -> ProviderCapabilities;
|
||||
fn self_test(&self) -> SelfTestReport;
|
||||
fn benchmark(&self) -> BenchmarkReport;
|
||||
}
|
||||
|
||||
``ProviderRegistry``::
|
||||
|
||||
OnceLock<Mutex<HashMap<&'static str, Box<dyn CryptoProvider + Send + Sync>>>>
|
||||
fn register(name, provider)
|
||||
fn get(name) -> Option<Arc<dyn CryptoProvider>>
|
||||
fn list() -> Vec<&'static str>
|
||||
|
||||
Step 3 — wolfSSL Submodule + ``ccc-crypto-wolfssl``
|
||||
|
||||
wolfSSL is vendored as a git submodule pinned to ``v5.7.2-stable``.
|
||||
The crate uses ``cmake`` + ``bindgen`` in ``build.rs`` to build and bind it.
|
||||
A ``stub_ffi`` feature bypasses the C build for fast unit-test cycles.
|
||||
|
||||
wolfSSL Phase 4 Algorithm Coverage
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
=================== ===========================================
|
||||
Category Algorithms
|
||||
=================== ===========================================
|
||||
AEAD AES-256-GCM, ChaCha20-Poly1305,
|
||||
XChaCha20-Poly1305
|
||||
KDF HKDF-SHA256/384/512, Argon2id, BLAKE2b-KDF
|
||||
MAC HMAC-SHA256/384/512, BLAKE2b-MAC
|
||||
Hash SHA-256/384/512, SHA3-256/512, BLAKE2b-512
|
||||
KEM X25519, X448
|
||||
KEM (Phase 5) ML-KEM-768, ML-KEM-1024, Classic McEliece
|
||||
=================== ===========================================
|
||||
|
||||
Capability Probe Strategy
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``WolfSslProvider::capabilities()`` runs a minimal probe call (encrypt 1 byte;
|
||||
decrypt; compare) per algorithm at startup. Sets ``available = probe_succeeded``.
|
||||
If the wolfSSL build omits PQ support, ML-KEM entries report
|
||||
``available: false`` gracefully.
|
||||
|
||||
Benchmark Strategy
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``WolfSslProvider::benchmark()`` encrypts a 1 MB buffer × 100 iterations per
|
||||
AEAD algorithm, measures wall-clock throughput, normalises to a 0–100
|
||||
``efficiency_score``. Run once at library init and cached.
|
||||
|
||||
|
||||
Step 4 — Conformance Test Suite
|
||||
|
||||
Location: ``tests/conformance/src/main.rs``
|
||||
|
||||
Run with ``cargo run -p ccc-conformance-tests`` and ``cargo test --workspace``.
|
||||
|
||||
========================= ================================
|
||||
Test Source
|
||||
========================= ================================
|
||||
AES-256-GCM NIST SP 800-38D vectors
|
||||
ChaCha20-Poly1305 RFC 8439 vectors
|
||||
XChaCha20-Poly1305 Extended nonce vectors
|
||||
HKDF-SHA256/512 RFC 5869 vectors
|
||||
HMAC-SHA256/512 RFC 4231 vectors
|
||||
SHA-256/512, SHA3, BLAKE2b FIPS / reference vectors
|
||||
X25519 DH RFC 7748 vectors
|
||||
X448 DH RFC 7748 vectors
|
||||
========================= ================================
|
||||
|
||||
**Gate**: ``ALL VECTORS PASSED`` must print before Milestone 1 is tagged.
|
||||
|
||||
|
||||
Step 5 — Architecture Documentation
|
||||
|
||||
``docs/ccc_rust_milestone1.rst`` covers:
|
||||
|
||||
* Crate dependency graph (ASCII)
|
||||
* "How to add a new provider" — 7-step trait checklist
|
||||
* ``algo: u32`` → cipher constant mapping table
|
||||
* Milestone 2 hand-off contract (API surface Milestone 2 must implement against)
|
||||
|
||||
|
||||
Milestone 1 Verification Gate
|
||||
|
||||
All of the following must pass before the ``v0.1.0`` tag is cut and Milestone 2
|
||||
work begins:
|
||||
|
||||
* ``cargo test --workspace`` — all unit tests pass
|
||||
* ``cargo run -p ccc-conformance-tests`` — ``ALL VECTORS PASSED``
|
||||
* ``cargo build --target aarch64-apple-ios`` — compiles
|
||||
* ``cargo build --target aarch64-linux-android`` — compiles
|
||||
* No ``flutter_rust_bridge``, Dart, or Flutter dependency anywhere in the workspace
|
||||
* ``cargo audit`` — no known CVEs in dependency tree
|
||||
|
||||
|
||||
Milestone 2 — ``ccc_dart_plugin`` (separate repository)
|
||||
|
||||
*(Planned — not started. Work begins after Milestone 1 gate passes.)*
|
||||
|
||||
A separate Dart/Flutter plugin package repository. It contains:
|
||||
|
||||
* A small Rust bridge crate that references ``ccc_rust`` via git tag:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[dependencies]
|
||||
ccc-crypto-core = { git = "https://github.com/letusmsg/ccc_rust", tag = "v0.1.0" }
|
||||
ccc-crypto-wolfssl = { git = "https://github.com/letusmsg/ccc_rust", tag = "v0.1.0" }
|
||||
flutter_rust_bridge = "2"
|
||||
|
||||
* ``flutter_rust_bridge_codegen generate`` output (``frb_generated.rs``, Dart bindings)
|
||||
* Flutter plugin scaffold: ``ios/``, ``android/``, ``macos/``
|
||||
* Dart API surface: ``CccCrypto``, ``CccSelfTest``, ``CccProviderCatalog``
|
||||
* Flutter integration tests (roundtrip encrypt/decrypt, self-test harness)
|
||||
|
||||
|
||||
Milestone 3 — LetUsMsg App Integration (existing repository)
|
||||
|
||||
*(Planned — not started. Work begins after Milestone 2 gate passes.)*
|
||||
|
||||
The existing ``letusmsg`` Flutter app adds ``ccc_dart_plugin`` as a pubspec
|
||||
dependency. Changes are confined to:
|
||||
|
||||
* ``crypto_wolfssl.dart`` — replace ``UnimplementedError`` stubs with plugin calls
|
||||
* ``ccc_provider_spec.dart`` — populate ``CccProviderCatalog`` at runtime
|
||||
* ``main.dart`` — call ``CccCrypto.cccInit()`` at startup
|
||||
* App debug screen — expose ``CccSelfTest.runAll()`` results
|
||||
|
||||
No Rust changes and no bridge changes are made in Milestone 3.
|
||||
|
||||
|
||||
Phase 8 — Stretch Goal Providers (Future)
|
||||
|
||||
*(Out of scope for Phase 4. Tracked here for future scheduling.)*
|
||||
|
||||
================== =====================================================
|
||||
Library Rust crate / approach
|
||||
================== =====================================================
|
||||
libsodium ``sodiumoxide`` or ``safe_libsodium``
|
||||
OpenSSL ``openssl`` crate
|
||||
BoringSSL ``boring`` crate
|
||||
RustCrypto Pure-Rust trait impls; no native dep
|
||||
liboqs Open Quantum Safe — ML-KEM, BIKE, HQC, Falcon,
|
||||
Dilithium, SPHINCS+
|
||||
Signal libsignal ``libsignal`` (Apache-2 subset)
|
||||
Botan ``botan`` crate
|
||||
mbedTLS ``mbedtls`` crate
|
||||
Nettle ``nettle-sys`` crate
|
||||
================== =====================================================
|
||||
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
==============================================
|
||||
CCC Rust Implementation — Phase Tracking
|
||||
==============================================
|
||||
|
||||
:Last Updated: 2026-02-25
|
||||
|
||||
Legend
|
||||
------
|
||||
|
||||
* ``[ ]`` Not started
|
||||
* ``[~]`` In progress
|
||||
* ``[x]`` Complete
|
||||
* ``[!]`` Blocked
|
||||
|
||||
----
|
||||
|
||||
Three-Milestone Overview
|
||||
------------------------
|
||||
|
||||
============= =================================== ============================
|
||||
Milestone Repository Status
|
||||
============= =================================== ============================
|
||||
**1 (this)** ``ccc_rust`` Complete
|
||||
**2** ``ccc_cryptography`` Not started
|
||||
**3** ``letusmsg`` (existing app) Not started
|
||||
============= =================================== ============================
|
||||
|
||||
Milestone 1 Verification Gate is now passing.
|
||||
Milestone 2 may begin when scheduled.
|
||||
Milestone 3 does not start until the Milestone 2 gate passes.
|
||||
|
||||
----
|
||||
|
||||
============================================================
|
||||
Milestone 1 — ``ccc_rust`` Pure Rust Crypto Library
|
||||
============================================================
|
||||
|
||||
Phase 1 — Cargo Workspace Scaffold
|
||||
----------------------------------
|
||||
|
||||
* ``[x]`` Create ``Cargo.toml`` (workspace manifest, 3 members — no bridge crate)
|
||||
* ``[x]`` Create ``rust-toolchain.toml`` (channel = "stable")
|
||||
* ``[x]`` Create ``.cargo/config.toml`` (cross-compile target aliases)
|
||||
* ``[x]`` Create ``vendors/README.md``
|
||||
|
||||
----
|
||||
|
||||
Phase 2 — ``ccc-crypto-core`` Trait Crate
|
||||
-----------------------------------------
|
||||
|
||||
* ``[x]`` Create ``crates/ccc-crypto-core/Cargo.toml``
|
||||
* ``[x]`` ``algorithms.rs`` — AeadAlgorithm, KdfAlgorithm, MacAlgorithm,
|
||||
HashAlgorithm, KemAlgorithm enums (values == cipher_constants.dart)
|
||||
* ``[x]`` ``capabilities.rs`` — AlgorithmCapability, ProviderCapabilities
|
||||
* ``[x]`` ``error.rs`` — CryptoError enum
|
||||
* ``[x]`` ``types.rs`` — KemKeyPair, SelfTestReport, BenchmarkReport,
|
||||
AlgoTestResult
|
||||
* ``[x]`` ``provider.rs`` — AeadProvider, KdfProvider, MacProvider,
|
||||
HashProvider, KemProvider traits; CryptoProvider umbrella trait
|
||||
* ``[x]`` ``registry.rs`` — ProviderRegistry (OnceLock<Mutex<...>>),
|
||||
register(), get(), list()
|
||||
* ``[x]`` ``lib.rs`` — re-exports all public items
|
||||
* ``[x]`` Unit tests for registry (5 passing)
|
||||
|
||||
----
|
||||
|
||||
Phase 3 — wolfSSL Submodule + ``ccc-crypto-wolfssl``
|
||||
-----------------------------------------------------
|
||||
|
||||
* ``[x]`` ``git submodule add`` wolfSSL → ``vendors/wolfssl``
|
||||
* ``[x]`` Pin submodule to ``v5.7.2-stable``
|
||||
* ``[x]`` Document pin in ``vendors/README.md``
|
||||
* ``[x]`` Create ``crates/ccc-crypto-wolfssl/Cargo.toml``
|
||||
* ``[x]`` ``build.rs`` — cmake build + bindgen; stub_ffi feature bypasses C build
|
||||
* ``[x]`` ``aead.rs`` — AES-256-GCM implementation
|
||||
|
||||
* ``[x]`` encrypt_aead (AES-256-GCM)
|
||||
* ``[x]`` decrypt_aead (AES-256-GCM)
|
||||
* ``[x]`` encrypt_aead (ChaCha20-Poly1305)
|
||||
* ``[x]`` decrypt_aead (ChaCha20-Poly1305)
|
||||
* ``[x]`` encrypt_aead (XChaCha20-Poly1305 via HChaCha20)
|
||||
* ``[x]`` decrypt_aead (XChaCha20-Poly1305)
|
||||
|
||||
* ``[x]`` ``kdf.rs`` — KDF implementations
|
||||
|
||||
* ``[x]`` HKDF-SHA256
|
||||
* ``[x]`` HKDF-SHA384
|
||||
* ``[x]`` HKDF-SHA512
|
||||
* ``[x]`` Argon2id (64 MB / 3 iter / 4 threads — matches DEFAULT_CIPHER_PARAMS)
|
||||
* ``[x]`` BLAKE2b-512 KDF
|
||||
|
||||
* ``[x]`` ``mac.rs`` — MAC implementations
|
||||
|
||||
* ``[x]`` HMAC-SHA256
|
||||
* ``[x]`` HMAC-SHA384
|
||||
* ``[x]`` HMAC-SHA512
|
||||
* ``[x]`` BLAKE2b-MAC (keyed)
|
||||
* ``[x]`` Constant-time verify
|
||||
|
||||
* ``[x]`` ``hash.rs`` — Hash implementations
|
||||
|
||||
* ``[x]`` SHA-256 / SHA-384 / SHA-512
|
||||
* ``[x]`` SHA3-256 / SHA3-512
|
||||
* ``[x]`` BLAKE2b-512
|
||||
|
||||
* ``[x]`` ``kem.rs`` — KEM implementations
|
||||
|
||||
* ``[x]`` X25519 (keygen + DH encap/decap)
|
||||
* ``[x]`` X448 (keygen + DH encap/decap)
|
||||
* ``[ ]`` ML-KEM-768 (deferred to Phase 5)
|
||||
* ``[ ]`` ML-KEM-1024 (deferred to Phase 5)
|
||||
* ``[ ]`` Classic McEliece (deferred to Phase 5)
|
||||
|
||||
* ``[x]`` ``capabilities.rs`` — probe-at-startup per algorithm
|
||||
* ``[x]`` ``capabilities.rs`` — benchmark() throughput micro-bench
|
||||
* ``[x]`` ``provider.rs`` — WolfSslProvider: CryptoProvider impl
|
||||
* ``[x]`` ``provider.rs`` — self_test() with embedded NIST vectors (AES-256-GCM, ChaCha20-Poly1305)
|
||||
* ``[x]`` Register WolfSslProvider in ProviderRegistry via init()
|
||||
* ``[x]`` Full native build verified (cmake builds clean, all conformance tests pass)
|
||||
|
||||
----
|
||||
|
||||
Phase 4 — Conformance Test Suite
|
||||
---------------------------------
|
||||
|
||||
* ``[x]`` NIST AES-256-GCM vectors (2 vectors)
|
||||
* ``[x]`` RFC 8439 ChaCha20-Poly1305 vectors
|
||||
* ``[x]`` RFC 5869 HKDF-SHA256 vectors (2 vectors)
|
||||
* ``[x]`` RFC 4231 HMAC-SHA256 vectors (2 vectors)
|
||||
* ``[x]`` FIPS hash vectors (SHA-256/512, SHA3-256, BLAKE2b-512)
|
||||
* ``[x]`` RFC 7748 X25519 DH test vectors
|
||||
* ``[x]`` RFC 7748 X448 DH test vectors
|
||||
* ``[x]`` XChaCha20-Poly1305 extended-nonce vectors
|
||||
* ``[x]`` ``cargo run -p ccc-conformance-tests`` passes (all current vectors)
|
||||
|
||||
----
|
||||
|
||||
Phase 5 — Architecture Documentation
|
||||
--------------------------------------
|
||||
|
||||
* ``[x]`` Create ``docs/ccc_rust_milestone1.rst``
|
||||
* ``[x]`` Crate dependency graph (ASCII diagram)
|
||||
* ``[x]`` "How to add a new provider" — 7-step trait checklist
|
||||
* ``[x]`` ``algo: u32`` → cipher constant mapping table
|
||||
* ``[x]`` Milestone 2 hand-off contract documented
|
||||
|
||||
----
|
||||
|
||||
Milestone 1 Verification Gate
|
||||
------------------------------
|
||||
|
||||
*All items must be checked before the* ``v0.1.0`` *tag is cut.*
|
||||
|
||||
* ``[x]`` ``cargo test --workspace`` — all pass
|
||||
* ``[x]`` ``cargo run -p ccc-conformance-tests`` — ALL VECTORS PASSED
|
||||
* ``[x]`` ``cargo build --target aarch64-apple-ios`` — success
|
||||
* ``[x]`` ``cargo build --target aarch64-linux-android`` — success
|
||||
* ``[x]`` No ``flutter_rust_bridge`` / Dart / Flutter dependency in workspace
|
||||
* ``[x]`` ``cargo audit`` — no known CVEs
|
||||
|
||||
----
|
||||
|
||||
============================================================
|
||||
Milestone 2 — ``ccc_cryptography`` Flutter Plugin
|
||||
===========================================================
|
||||
|
||||
*(Not started — begins after Milestone 1 gate passes)*
|
||||
|
||||
Phase 1 — New Repository Setup
|
||||
-------------------------------
|
||||
|
||||
* ``[ ]`` Create ``ccc_cryptography`` repository
|
||||
* ``[ ]`` Flutter plugin scaffold (``pubspec.yaml``, ``ios/``, ``android/``, ``macos/``)
|
||||
* ``[ ]`` Rust bridge crate with ``crate-type = ["cdylib", "staticlib"]``
|
||||
* ``[ ]`` Add ``flutter_rust_bridge = "2"`` dependency
|
||||
* ``[ ]`` Reference ``ccc_rust`` via git tag ``v0.1.0``
|
||||
|
||||
----
|
||||
|
||||
Phase 2 — Bridge Crate
|
||||
----------------------
|
||||
|
||||
* ``[ ]`` ``dto.rs`` — CapabilitiesDto, KemKeyPairDto, KemEncapDto,
|
||||
SelfTestDto, AlgoTestResultDto; From<core types> impls
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_init()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_list_providers()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_capabilities() / ccc_available_algorithms()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_aead_encrypt() / ccc_aead_decrypt()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_kdf_derive()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_mac_compute() / ccc_mac_verify()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_hash()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_kem_generate_keypair()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_kem_encapsulate() / ccc_kem_decapsulate()
|
||||
* ``[ ]`` ``bridge.rs`` — ccc_self_test()
|
||||
|
||||
----
|
||||
|
||||
Phase 3 — Codegen + Plugin Build
|
||||
---------------------------------
|
||||
|
||||
* ``[ ]`` Run ``flutter_rust_bridge_codegen generate``
|
||||
* ``[ ]`` Verify generated Dart bindings compile
|
||||
* ``[ ]`` ``flutter build ios`` succeeds (static lib linked)
|
||||
* ``[ ]`` ``flutter build apk`` succeeds (cdylib linked)
|
||||
* ``[ ]`` ``flutter build macos`` succeeds
|
||||
|
||||
----
|
||||
|
||||
Phase 4 — Dart API Layer
|
||||
------------------------
|
||||
|
||||
* ``[ ]`` ``CccCrypto`` class (wraps all bridge calls)
|
||||
* ``[ ]`` ``CccSelfTest`` class (wraps ccc_self_test())
|
||||
* ``[ ]`` ``CccProviderCatalog`` (runtime-populated from ccc_capabilities())
|
||||
|
||||
----
|
||||
|
||||
Phase 5 — Flutter Integration Tests
|
||||
------------------------------------
|
||||
|
||||
* ``[ ]`` Roundtrip encrypt/decrypt 1 KB (AES-256-GCM)
|
||||
* ``[ ]`` Roundtrip encrypt/decrypt 1 KB (ChaCha20-Poly1305)
|
||||
* ``[ ]`` ``CccSelfTest.runAll()`` — all-pass
|
||||
|
||||
----
|
||||
|
||||
Milestone 2 Verification Gate
|
||||
------------------------------
|
||||
|
||||
* ``[ ]`` All Flutter integration tests pass on iOS simulator
|
||||
* ``[ ]`` All Flutter integration tests pass on Android emulator
|
||||
* ``[ ]`` Package published / tagged ``v0.1.0``
|
||||
|
||||
----
|
||||
|
||||
============================================================
|
||||
Milestone 3 — LetUsMsg App Integration
|
||||
============================================================
|
||||
|
||||
*(Not started — begins after Milestone 2 gate passes)*
|
||||
|
||||
* ``[ ]`` Add ``ccc_cryptography`` to ``letusmsg`` `pubspec.yaml``
|
||||
* ``[ ]`` Wire ``crypto_wolfssl.dart`` encrypt/decrypt → bridge calls
|
||||
* ``[ ]`` Call ``CccCrypto.cccInit()`` at app startup
|
||||
* ``[ ]`` Populate ``CccProviderCatalog`` from runtime capabilities
|
||||
* ``[ ]`` Expose ``CccSelfTest.runAll()`` in app debug screen
|
||||
* ``[ ]`` End-to-end integration test (send + receive encrypted message)
|
||||
|
||||
----
|
||||
|
||||
Phase 8 — Stretch Goal Providers (Future)
|
||||
------------------------------------------
|
||||
|
||||
*(Out of scope for Phase 4. Tracked here for future scheduling.)*
|
||||
|
||||
* ``[ ]`` libsodium (``sodiumoxide`` / ``safe_libsodium``)
|
||||
* ``[ ]`` OpenSSL (``openssl`` crate)
|
||||
* ``[ ]`` BoringSSL (``boring`` crate)
|
||||
* ``[ ]`` RustCrypto (pure-Rust, no native dep)
|
||||
* ``[ ]`` liboqs — ML-KEM, BIKE, HQC, Falcon, Dilithium, SPHINCS+
|
||||
* ``[ ]`` Signal ``libsignal``
|
||||
* ``[ ]`` Botan
|
||||
* ``[ ]`` mbedTLS
|
||||
* ``[ ]`` Nettle
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:ccc_cryptography/ccc_cryptography.dart';
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
setUpAll(() async => await RustLib.init());
|
||||
test('Can call rust function', () async {
|
||||
expect(greet(name: "Tom"), "Hello, Tom!");
|
||||
});
|
||||
}
|
||||
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '13.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
target 'RunnerTests' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
import 'package:ccc_cryptography/src/rust/api/simple.dart';
|
||||
import 'package:ccc_cryptography/src/rust/frb_generated.dart';
|
||||
|
||||
import 'package:ccc_cryptography/ccc_cryptography.dart' as ccc_cryptography;
|
||||
|
||||
void main() {
|
||||
Future<void> main() async {
|
||||
await RustLib.init();
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
|
|
@ -15,57 +15,25 @@ class MyApp extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
late int sumResult;
|
||||
late Future<int> sumAsyncResult;
|
||||
late String greetResult;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
sumResult = ccc_cryptography.sum(1, 2);
|
||||
sumAsyncResult = ccc_cryptography.sumAsync(3, 4);
|
||||
greetResult = greet(name: 'Flutter');
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const textStyle = TextStyle(fontSize: 25);
|
||||
const spacerSmall = SizedBox(height: 10);
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Native Packages'),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: const .all(10),
|
||||
child: Column(
|
||||
children: [
|
||||
const Text(
|
||||
'This calls a native function through FFI that is shipped as source in the package. '
|
||||
'The native code is built as part of the Flutter Runner build.',
|
||||
style: textStyle,
|
||||
textAlign: .center,
|
||||
),
|
||||
spacerSmall,
|
||||
Text(
|
||||
'sum(1, 2) = $sumResult',
|
||||
style: textStyle,
|
||||
textAlign: .center,
|
||||
),
|
||||
spacerSmall,
|
||||
FutureBuilder<int>(
|
||||
future: sumAsyncResult,
|
||||
builder: (BuildContext context, AsyncSnapshot<int> value) {
|
||||
final displayValue =
|
||||
(value.hasData) ? value.data : 'loading';
|
||||
return Text(
|
||||
'await sumAsync(3, 4) = $displayValue',
|
||||
style: textStyle,
|
||||
textAlign: .center,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
appBar: AppBar(title: const Text('ccc_cryptography')),
|
||||
body: Center(
|
||||
child: Text(
|
||||
greetResult,
|
||||
style: textStyle,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
platform :osx, '10.15'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_macos_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
|
||||
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
|
||||
target 'RunnerTests' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_macos_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
|
@ -27,6 +27,8 @@
|
|||
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
||||
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
||||
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
||||
C9D9D80953306779817A01D7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 038972E62E6D13C2A55A0B7F /* Pods_Runner.framework */; };
|
||||
CC6FDE117C14C0F98D1BA8BB /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5AA6C665A590100A722C2D2 /* Pods_RunnerTests.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
|
@ -60,11 +62,13 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
038972E62E6D13C2A55A0B7F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0988C826A2FD255462F9808A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
|
||||
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
|
||||
33CC10ED2044A3C60003C045 /* ccc_cryptography_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ccc_cryptography_example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33CC10ED2044A3C60003C045 /* ccc_cryptography_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ccc_cryptography_example.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
|
||||
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
|
|
@ -77,7 +81,13 @@
|
|||
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
|
||||
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||
86D70DA30699567E710A0459 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9D35F14235952B671983F7E0 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
A5B81D3E19756CB2D0C8B009 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
A81A44EB7B90A16EAADE4FA6 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
BA626D8003BA6E48536EE306 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
D5AA6C665A590100A722C2D2 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -85,6 +95,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CC6FDE117C14C0F98D1BA8BB /* Pods_RunnerTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -92,6 +103,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C9D9D80953306779817A01D7 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -125,6 +137,7 @@
|
|||
331C80D6294CF71000263BE5 /* RunnerTests */,
|
||||
33CC10EE2044A3C60003C045 /* Products */,
|
||||
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
||||
DE0D4D416823266B5CAAEDA7 /* Pods */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
|
@ -175,10 +188,26 @@
|
|||
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
038972E62E6D13C2A55A0B7F /* Pods_Runner.framework */,
|
||||
D5AA6C665A590100A722C2D2 /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DE0D4D416823266B5CAAEDA7 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0988C826A2FD255462F9808A /* Pods-Runner.debug.xcconfig */,
|
||||
86D70DA30699567E710A0459 /* Pods-Runner.release.xcconfig */,
|
||||
BA626D8003BA6E48536EE306 /* Pods-Runner.profile.xcconfig */,
|
||||
A81A44EB7B90A16EAADE4FA6 /* Pods-RunnerTests.debug.xcconfig */,
|
||||
9D35F14235952B671983F7E0 /* Pods-RunnerTests.release.xcconfig */,
|
||||
A5B81D3E19756CB2D0C8B009 /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
|
@ -186,6 +215,7 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||
buildPhases = (
|
||||
086D907707E0A9BB81BA038A /* [CP] Check Pods Manifest.lock */,
|
||||
331C80D1294CF70F00263BE5 /* Sources */,
|
||||
331C80D2294CF70F00263BE5 /* Frameworks */,
|
||||
331C80D3294CF70F00263BE5 /* Resources */,
|
||||
|
|
@ -204,11 +234,13 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
C86250B37FA1453AAEC9A1C2 /* [CP] Check Pods Manifest.lock */,
|
||||
33CC10E92044A3C60003C045 /* Sources */,
|
||||
33CC10EA2044A3C60003C045 /* Frameworks */,
|
||||
33CC10EB2044A3C60003C045 /* Resources */,
|
||||
33CC110E2044A8840003C045 /* Bundle Framework */,
|
||||
3399D490228B24CF009A79C7 /* ShellScript */,
|
||||
78F7E7C7FE2E75BBB3819847 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -291,6 +323,28 @@
|
|||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
086D907707E0A9BB81BA038A /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3399D490228B24CF009A79C7 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
|
|
@ -329,6 +383,45 @@
|
|||
shellPath = /bin/sh;
|
||||
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
||||
};
|
||||
78F7E7C7FE2E75BBB3819847 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C86250B37FA1453AAEC9A1C2 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
|
@ -380,6 +473,7 @@
|
|||
/* Begin XCBuildConfiguration section */
|
||||
331C80DB294CF71000263BE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = A81A44EB7B90A16EAADE4FA6 /* Pods-RunnerTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
|
@ -394,6 +488,7 @@
|
|||
};
|
||||
331C80DC294CF71000263BE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9D35F14235952B671983F7E0 /* Pods-RunnerTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
|
@ -408,6 +503,7 @@
|
|||
};
|
||||
331C80DD294CF71000263BE5 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = A5B81D3E19756CB2D0C8B009 /* Pods-RunnerTests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
|
|
|||
|
|
@ -4,4 +4,7 @@
|
|||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ dev_dependencies:
|
|||
# package. See that file for information about deactivating specific lint
|
||||
# rules and activating additional ones.
|
||||
flutter_lints: ^6.0.0
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
|
|
|||
19
ffigen.yaml
19
ffigen.yaml
|
|
@ -1,19 +0,0 @@
|
|||
# Run with `dart run ffigen --config ffigen.yaml`.
|
||||
name: CccCryptographyBindings
|
||||
description: |
|
||||
Bindings for `src/ccc_cryptography.h`.
|
||||
|
||||
Regenerate bindings with `dart run ffigen --config ffigen.yaml`.
|
||||
output: 'lib/ccc_cryptography_bindings_generated.dart'
|
||||
headers:
|
||||
entry-points:
|
||||
- 'src/ccc_cryptography.h'
|
||||
include-directives:
|
||||
- 'src/ccc_cryptography.h'
|
||||
preamble: |
|
||||
// ignore_for_file: always_specify_types
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
comments:
|
||||
style: any
|
||||
length: full
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
rust_input: crate::api
|
||||
dart_output: lib/src/rust
|
||||
rust_root: rust/
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
// Relative import to be able to reuse the C sources.
|
||||
// See the comment in ../ccc_cryptography.podspec for more information.
|
||||
#include "../../src/ccc_cryptography.c"
|
||||
|
|
@ -0,0 +1 @@
|
|||
// This is an empty file to force CocoaPods to create a framework.
|
||||
|
|
@ -20,9 +20,26 @@ A new Flutter FFI plugin project.
|
|||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.dependency 'Flutter'
|
||||
s.platform = :ios, '13.0'
|
||||
s.platform = :ios, '11.0'
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
|
||||
s.swift_version = '5.0'
|
||||
end
|
||||
|
||||
s.script_phase = {
|
||||
:name => 'Build Rust library',
|
||||
# First argument is relative path to the `rust` folder, second is name of rust library
|
||||
:script => 'sh "$PODS_TARGET_SRCROOT/../cargokit/build_pod.sh" ../rust ccc_cryptography',
|
||||
:execution_position => :before_compile,
|
||||
:input_files => ['${BUILT_PRODUCTS_DIR}/cargokit_phony'],
|
||||
# Let XCode know that the static library referenced in -force_load below is
|
||||
# created by this build step.
|
||||
:output_files => ["${BUILT_PRODUCTS_DIR}/libccc_cryptography.a"],
|
||||
}
|
||||
s.pod_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||
'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/libccc_cryptography.a',
|
||||
}
|
||||
end
|
||||
|
|
@ -1,131 +1,147 @@
|
|||
// The original content is temporarily commented out to allow generating a self-contained demo - feel free to uncomment later.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
// // The original content is temporarily commented out to allow generating a self-contained demo - feel free to uncomment later.
|
||||
//
|
||||
// //
|
||||
// // import 'dart:async';
|
||||
// // import 'dart:ffi';
|
||||
// // import 'dart:io';
|
||||
// // import 'dart:isolate';
|
||||
// //
|
||||
// // import 'ccc_cryptography_bindings_generated.dart';
|
||||
// //
|
||||
// // /// A very short-lived native function.
|
||||
// // ///
|
||||
// // /// For very short-lived functions, it is fine to call them on the main isolate.
|
||||
// // /// They will block the Dart execution while running the native function, so
|
||||
// // /// only do this for native functions which are guaranteed to be short-lived.
|
||||
// // int sum(int a, int b) => _bindings.sum(a, b);
|
||||
// //
|
||||
// // /// A longer lived native function, which occupies the thread calling it.
|
||||
// // ///
|
||||
// // /// Do not call these kind of native functions in the main isolate. They will
|
||||
// // /// block Dart execution. This will cause dropped frames in Flutter applications.
|
||||
// // /// Instead, call these native functions on a separate isolate.
|
||||
// // ///
|
||||
// // /// Modify this to suit your own use case. Example use cases:
|
||||
// // ///
|
||||
// // /// 1. Reuse a single isolate for various different kinds of requests.
|
||||
// // /// 2. Use multiple helper isolates for parallel execution.
|
||||
// // Future<int> sumAsync(int a, int b) async {
|
||||
// // final SendPort helperIsolateSendPort = await _helperIsolateSendPort;
|
||||
// // final int requestId = _nextSumRequestId++;
|
||||
// // final _SumRequest request = _SumRequest(requestId, a, b);
|
||||
// // final Completer<int> completer = Completer<int>();
|
||||
// // _sumRequests[requestId] = completer;
|
||||
// // helperIsolateSendPort.send(request);
|
||||
// // return completer.future;
|
||||
// // }
|
||||
// //
|
||||
// // const String _libName = 'ccc_cryptography';
|
||||
// //
|
||||
// // /// The dynamic library in which the symbols for [CccCryptographyBindings] can be found.
|
||||
// // final DynamicLibrary _dylib = () {
|
||||
// // if (Platform.isMacOS || Platform.isIOS) {
|
||||
// // return DynamicLibrary.open('$_libName.framework/$_libName');
|
||||
// // }
|
||||
// // if (Platform.isAndroid || Platform.isLinux) {
|
||||
// // return DynamicLibrary.open('lib$_libName.so');
|
||||
// // }
|
||||
// // if (Platform.isWindows) {
|
||||
// // return DynamicLibrary.open('$_libName.dll');
|
||||
// // }
|
||||
// // throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
|
||||
// // }();
|
||||
// //
|
||||
// // /// The bindings to the native functions in [_dylib].
|
||||
// // final CccCryptographyBindings _bindings = CccCryptographyBindings(_dylib);
|
||||
// //
|
||||
// //
|
||||
// // /// A request to compute `sum`.
|
||||
// // ///
|
||||
// // /// Typically sent from one isolate to another.
|
||||
// // class _SumRequest {
|
||||
// // final int id;
|
||||
// // final int a;
|
||||
// // final int b;
|
||||
// //
|
||||
// // const _SumRequest(this.id, this.a, this.b);
|
||||
// // }
|
||||
// //
|
||||
// // /// A response with the result of `sum`.
|
||||
// // ///
|
||||
// // /// Typically sent from one isolate to another.
|
||||
// // class _SumResponse {
|
||||
// // final int id;
|
||||
// // final int result;
|
||||
// //
|
||||
// // const _SumResponse(this.id, this.result);
|
||||
// // }
|
||||
// //
|
||||
// // /// Counter to identify [_SumRequest]s and [_SumResponse]s.
|
||||
// // int _nextSumRequestId = 0;
|
||||
// //
|
||||
// // /// Mapping from [_SumRequest] `id`s to the completers corresponding to the correct future of the pending request.
|
||||
// // final Map<int, Completer<int>> _sumRequests = <int, Completer<int>>{};
|
||||
// //
|
||||
// // /// The SendPort belonging to the helper isolate.
|
||||
// // Future<SendPort> _helperIsolateSendPort = () async {
|
||||
// // // The helper isolate is going to send us back a SendPort, which we want to
|
||||
// // // wait for.
|
||||
// // final Completer<SendPort> completer = Completer<SendPort>();
|
||||
// //
|
||||
// // // Receive port on the main isolate to receive messages from the helper.
|
||||
// // // We receive two types of messages:
|
||||
// // // 1. A port to send messages on.
|
||||
// // // 2. Responses to requests we sent.
|
||||
// // final ReceivePort receivePort = ReceivePort()
|
||||
// // ..listen((dynamic data) {
|
||||
// // if (data is SendPort) {
|
||||
// // // The helper isolate sent us the port on which we can sent it requests.
|
||||
// // completer.complete(data);
|
||||
// // return;
|
||||
// // }
|
||||
// // if (data is _SumResponse) {
|
||||
// // // The helper isolate sent us a response to a request we sent.
|
||||
// // final Completer<int> completer = _sumRequests[data.id]!;
|
||||
// // _sumRequests.remove(data.id);
|
||||
// // completer.complete(data.result);
|
||||
// // return;
|
||||
// // }
|
||||
// // throw UnsupportedError('Unsupported message type: ${data.runtimeType}');
|
||||
// // });
|
||||
// //
|
||||
// // // Start the helper isolate.
|
||||
// // await Isolate.spawn((SendPort sendPort) async {
|
||||
// // final ReceivePort helperReceivePort = ReceivePort()
|
||||
// // ..listen((dynamic data) {
|
||||
// // // On the helper isolate listen to requests and respond to them.
|
||||
// // if (data is _SumRequest) {
|
||||
// // final int result = _bindings.sum_long_running(data.a, data.b);
|
||||
// // final _SumResponse response = _SumResponse(data.id, result);
|
||||
// // sendPort.send(response);
|
||||
// // return;
|
||||
// // }
|
||||
// // throw UnsupportedError('Unsupported message type: ${data.runtimeType}');
|
||||
// // });
|
||||
// //
|
||||
// // // Send the port to the main isolate on which we can receive requests.
|
||||
// // sendPort.send(helperReceivePort.sendPort);
|
||||
// // }, receivePort.sendPort);
|
||||
// //
|
||||
// // // Wait until the helper isolate has sent us back the SendPort on which we
|
||||
// // // can start sending requests.
|
||||
// // return completer.future;
|
||||
// // }();
|
||||
// //
|
||||
//
|
||||
// library ccc_cryptography;
|
||||
//
|
||||
// export 'src/rust/api/simple.dart';
|
||||
// export 'src/rust/frb_generated.dart' show RustLib;
|
||||
//
|
||||
|
||||
import 'ccc_cryptography_bindings_generated.dart';
|
||||
library;
|
||||
|
||||
/// A very short-lived native function.
|
||||
///
|
||||
/// For very short-lived functions, it is fine to call them on the main isolate.
|
||||
/// They will block the Dart execution while running the native function, so
|
||||
/// only do this for native functions which are guaranteed to be short-lived.
|
||||
int sum(int a, int b) => _bindings.sum(a, b);
|
||||
|
||||
/// A longer lived native function, which occupies the thread calling it.
|
||||
///
|
||||
/// Do not call these kind of native functions in the main isolate. They will
|
||||
/// block Dart execution. This will cause dropped frames in Flutter applications.
|
||||
/// Instead, call these native functions on a separate isolate.
|
||||
///
|
||||
/// Modify this to suit your own use case. Example use cases:
|
||||
///
|
||||
/// 1. Reuse a single isolate for various different kinds of requests.
|
||||
/// 2. Use multiple helper isolates for parallel execution.
|
||||
Future<int> sumAsync(int a, int b) async {
|
||||
final SendPort helperIsolateSendPort = await _helperIsolateSendPort;
|
||||
final int requestId = _nextSumRequestId++;
|
||||
final _SumRequest request = _SumRequest(requestId, a, b);
|
||||
final Completer<int> completer = Completer<int>();
|
||||
_sumRequests[requestId] = completer;
|
||||
helperIsolateSendPort.send(request);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
const String _libName = 'ccc_cryptography';
|
||||
|
||||
/// The dynamic library in which the symbols for [CccCryptographyBindings] can be found.
|
||||
final DynamicLibrary _dylib = () {
|
||||
if (Platform.isMacOS || Platform.isIOS) {
|
||||
return DynamicLibrary.open('$_libName.framework/$_libName');
|
||||
}
|
||||
if (Platform.isAndroid || Platform.isLinux) {
|
||||
return DynamicLibrary.open('lib$_libName.so');
|
||||
}
|
||||
if (Platform.isWindows) {
|
||||
return DynamicLibrary.open('$_libName.dll');
|
||||
}
|
||||
throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
|
||||
}();
|
||||
|
||||
/// The bindings to the native functions in [_dylib].
|
||||
final CccCryptographyBindings _bindings = CccCryptographyBindings(_dylib);
|
||||
|
||||
|
||||
/// A request to compute `sum`.
|
||||
///
|
||||
/// Typically sent from one isolate to another.
|
||||
class _SumRequest {
|
||||
final int id;
|
||||
final int a;
|
||||
final int b;
|
||||
|
||||
const _SumRequest(this.id, this.a, this.b);
|
||||
}
|
||||
|
||||
/// A response with the result of `sum`.
|
||||
///
|
||||
/// Typically sent from one isolate to another.
|
||||
class _SumResponse {
|
||||
final int id;
|
||||
final int result;
|
||||
|
||||
const _SumResponse(this.id, this.result);
|
||||
}
|
||||
|
||||
/// Counter to identify [_SumRequest]s and [_SumResponse]s.
|
||||
int _nextSumRequestId = 0;
|
||||
|
||||
/// Mapping from [_SumRequest] `id`s to the completers corresponding to the correct future of the pending request.
|
||||
final Map<int, Completer<int>> _sumRequests = <int, Completer<int>>{};
|
||||
|
||||
/// The SendPort belonging to the helper isolate.
|
||||
Future<SendPort> _helperIsolateSendPort = () async {
|
||||
// The helper isolate is going to send us back a SendPort, which we want to
|
||||
// wait for.
|
||||
final Completer<SendPort> completer = Completer<SendPort>();
|
||||
|
||||
// Receive port on the main isolate to receive messages from the helper.
|
||||
// We receive two types of messages:
|
||||
// 1. A port to send messages on.
|
||||
// 2. Responses to requests we sent.
|
||||
final ReceivePort receivePort = ReceivePort()
|
||||
..listen((dynamic data) {
|
||||
if (data is SendPort) {
|
||||
// The helper isolate sent us the port on which we can sent it requests.
|
||||
completer.complete(data);
|
||||
return;
|
||||
}
|
||||
if (data is _SumResponse) {
|
||||
// The helper isolate sent us a response to a request we sent.
|
||||
final Completer<int> completer = _sumRequests[data.id]!;
|
||||
_sumRequests.remove(data.id);
|
||||
completer.complete(data.result);
|
||||
return;
|
||||
}
|
||||
throw UnsupportedError('Unsupported message type: ${data.runtimeType}');
|
||||
});
|
||||
|
||||
// Start the helper isolate.
|
||||
await Isolate.spawn((SendPort sendPort) async {
|
||||
final ReceivePort helperReceivePort = ReceivePort()
|
||||
..listen((dynamic data) {
|
||||
// On the helper isolate listen to requests and respond to them.
|
||||
if (data is _SumRequest) {
|
||||
final int result = _bindings.sum_long_running(data.a, data.b);
|
||||
final _SumResponse response = _SumResponse(data.id, result);
|
||||
sendPort.send(response);
|
||||
return;
|
||||
}
|
||||
throw UnsupportedError('Unsupported message type: ${data.runtimeType}');
|
||||
});
|
||||
|
||||
// Send the port to the main isolate on which we can receive requests.
|
||||
sendPort.send(helperReceivePort.sendPort);
|
||||
}, receivePort.sendPort);
|
||||
|
||||
// Wait until the helper isolate has sent us back the SendPort on which we
|
||||
// can start sending requests.
|
||||
return completer.future;
|
||||
}();
|
||||
export 'src/rust/api/simple.dart';
|
||||
export 'src/rust/frb_generated.dart' show RustLib;
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
// ignore_for_file: always_specify_types
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
// AUTO GENERATED FILE, DO NOT EDIT.
|
||||
//
|
||||
// Generated by `package:ffigen`.
|
||||
// ignore_for_file: type=lint
|
||||
import 'dart:ffi' as ffi;
|
||||
|
||||
/// Bindings for `src/ccc_cryptography.h`.
|
||||
///
|
||||
/// Regenerate bindings with `dart run ffigen --config ffigen.yaml`.
|
||||
///
|
||||
class CccCryptographyBindings {
|
||||
/// Holds the symbol lookup function.
|
||||
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
_lookup;
|
||||
|
||||
/// The symbols are looked up in [dynamicLibrary].
|
||||
CccCryptographyBindings(ffi.DynamicLibrary dynamicLibrary)
|
||||
: _lookup = dynamicLibrary.lookup;
|
||||
|
||||
/// The symbols are looked up with [lookup].
|
||||
CccCryptographyBindings.fromLookup(
|
||||
ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
lookup)
|
||||
: _lookup = lookup;
|
||||
|
||||
/// A very short-lived native function.
|
||||
///
|
||||
/// For very short-lived functions, it is fine to call them on the main isolate.
|
||||
/// They will block the Dart execution while running the native function, so
|
||||
/// only do this for native functions which are guaranteed to be short-lived.
|
||||
int sum(
|
||||
int a,
|
||||
int b,
|
||||
) {
|
||||
return _sum(
|
||||
a,
|
||||
b,
|
||||
);
|
||||
}
|
||||
|
||||
late final _sumPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int)>>('sum');
|
||||
late final _sum = _sumPtr.asFunction<int Function(int, int)>();
|
||||
|
||||
/// A longer lived native function, which occupies the thread calling it.
|
||||
///
|
||||
/// Do not call these kind of native functions in the main isolate. They will
|
||||
/// block Dart execution. This will cause dropped frames in Flutter applications.
|
||||
/// Instead, call these native functions on a separate isolate.
|
||||
int sum_long_running(
|
||||
int a,
|
||||
int b,
|
||||
) {
|
||||
return _sum_long_running(
|
||||
a,
|
||||
b,
|
||||
);
|
||||
}
|
||||
|
||||
late final _sum_long_runningPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Int Function(ffi.Int, ffi.Int)>>(
|
||||
'sum_long_running');
|
||||
late final _sum_long_running =
|
||||
_sum_long_runningPtr.asFunction<int Function(int, int)>();
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// This file is automatically generated, so please do not edit it.
|
||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||
|
||||
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
|
||||
|
||||
import '../frb_generated.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
String greet({required String name}) =>
|
||||
RustLib.instance.api.crateApiSimpleGreet(name: name);
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
// This file is automatically generated, so please do not edit it.
|
||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||
|
||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||
|
||||
import 'api/simple.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'frb_generated.dart';
|
||||
import 'frb_generated.io.dart'
|
||||
if (dart.library.js_interop) 'frb_generated.web.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
|
||||
|
||||
/// Main entrypoint of the Rust API
|
||||
class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
|
||||
@internal
|
||||
static final instance = RustLib._();
|
||||
|
||||
RustLib._();
|
||||
|
||||
/// Initialize flutter_rust_bridge
|
||||
static Future<void> init({
|
||||
RustLibApi? api,
|
||||
BaseHandler? handler,
|
||||
ExternalLibrary? externalLibrary,
|
||||
bool forceSameCodegenVersion = true,
|
||||
}) async {
|
||||
await instance.initImpl(
|
||||
api: api,
|
||||
handler: handler,
|
||||
externalLibrary: externalLibrary,
|
||||
forceSameCodegenVersion: forceSameCodegenVersion,
|
||||
);
|
||||
}
|
||||
|
||||
/// Initialize flutter_rust_bridge in mock mode.
|
||||
/// No libraries for FFI are loaded.
|
||||
static void initMock({required RustLibApi api}) {
|
||||
instance.initMockImpl(api: api);
|
||||
}
|
||||
|
||||
/// Dispose flutter_rust_bridge
|
||||
///
|
||||
/// The call to this function is optional, since flutter_rust_bridge (and everything else)
|
||||
/// is automatically disposed when the app stops.
|
||||
static void dispose() => instance.disposeImpl();
|
||||
|
||||
@override
|
||||
ApiImplConstructor<RustLibApiImpl, RustLibWire> get apiImplConstructor =>
|
||||
RustLibApiImpl.new;
|
||||
|
||||
@override
|
||||
WireConstructor<RustLibWire> get wireConstructor =>
|
||||
RustLibWire.fromExternalLibrary;
|
||||
|
||||
@override
|
||||
Future<void> executeRustInitializers() async {
|
||||
await api.crateApiSimpleInitApp();
|
||||
}
|
||||
|
||||
@override
|
||||
ExternalLibraryLoaderConfig get defaultExternalLibraryLoaderConfig =>
|
||||
kDefaultExternalLibraryLoaderConfig;
|
||||
|
||||
@override
|
||||
String get codegenVersion => '2.11.1';
|
||||
|
||||
@override
|
||||
int get rustContentHash => -1918914929;
|
||||
|
||||
static const kDefaultExternalLibraryLoaderConfig =
|
||||
ExternalLibraryLoaderConfig(
|
||||
stem: 'ccc_cryptography',
|
||||
ioDirectory: 'rust/target/release/',
|
||||
webPrefix: 'pkg/',
|
||||
);
|
||||
}
|
||||
|
||||
abstract class RustLibApi extends BaseApi {
|
||||
String crateApiSimpleGreet({required String name});
|
||||
|
||||
Future<void> crateApiSimpleInitApp();
|
||||
}
|
||||
|
||||
class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
||||
RustLibApiImpl({
|
||||
required super.handler,
|
||||
required super.wire,
|
||||
required super.generalizedFrbRustBinding,
|
||||
required super.portManager,
|
||||
});
|
||||
|
||||
@override
|
||||
String crateApiSimpleGreet({required String name}) {
|
||||
return handler.executeSync(
|
||||
SyncTask(
|
||||
callFfi: () {
|
||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
||||
sse_encode_String(name, serializer);
|
||||
return pdeCallFfi(generalizedFrbRustBinding, serializer, funcId: 1)!;
|
||||
},
|
||||
codec: SseCodec(
|
||||
decodeSuccessData: sse_decode_String,
|
||||
decodeErrorData: null,
|
||||
),
|
||||
constMeta: kCrateApiSimpleGreetConstMeta,
|
||||
argValues: [name],
|
||||
apiImpl: this,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiSimpleGreetConstMeta =>
|
||||
const TaskConstMeta(debugName: "greet", argNames: ["name"]);
|
||||
|
||||
@override
|
||||
Future<void> crateApiSimpleInitApp() {
|
||||
return handler.executeNormal(
|
||||
NormalTask(
|
||||
callFfi: (port_) {
|
||||
final serializer = SseSerializer(generalizedFrbRustBinding);
|
||||
pdeCallFfi(
|
||||
generalizedFrbRustBinding,
|
||||
serializer,
|
||||
funcId: 2,
|
||||
port: port_,
|
||||
);
|
||||
},
|
||||
codec: SseCodec(
|
||||
decodeSuccessData: sse_decode_unit,
|
||||
decodeErrorData: null,
|
||||
),
|
||||
constMeta: kCrateApiSimpleInitAppConstMeta,
|
||||
argValues: [],
|
||||
apiImpl: this,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TaskConstMeta get kCrateApiSimpleInitAppConstMeta =>
|
||||
const TaskConstMeta(debugName: "init_app", argNames: []);
|
||||
|
||||
@protected
|
||||
String dco_decode_String(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw as String;
|
||||
}
|
||||
|
||||
@protected
|
||||
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw as Uint8List;
|
||||
}
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return raw as int;
|
||||
}
|
||||
|
||||
@protected
|
||||
void dco_decode_unit(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return;
|
||||
}
|
||||
|
||||
@protected
|
||||
String sse_decode_String(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
var inner = sse_decode_list_prim_u_8_strict(deserializer);
|
||||
return utf8.decoder.convert(inner);
|
||||
}
|
||||
|
||||
@protected
|
||||
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
var len_ = sse_decode_i_32(deserializer);
|
||||
return deserializer.buffer.getUint8List(len_);
|
||||
}
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
return deserializer.buffer.getUint8();
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_decode_unit(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
}
|
||||
|
||||
@protected
|
||||
int sse_decode_i_32(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
return deserializer.buffer.getInt32();
|
||||
}
|
||||
|
||||
@protected
|
||||
bool sse_decode_bool(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
return deserializer.buffer.getUint8() != 0;
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_String(String self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_list_prim_u_8_strict(
|
||||
Uint8List self,
|
||||
SseSerializer serializer,
|
||||
) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_i_32(self.length, serializer);
|
||||
serializer.buffer.putUint8List(self);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_u_8(int self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
serializer.buffer.putUint8(self);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_unit(void self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_i_32(int self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
serializer.buffer.putInt32(self);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_bool(bool self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
serializer.buffer.putUint8(self ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
// This file is automatically generated, so please do not edit it.
|
||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||
|
||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||
|
||||
import 'api/simple.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:ffi' as ffi;
|
||||
import 'frb_generated.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_io.dart';
|
||||
|
||||
abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
RustLibApiImplPlatform({
|
||||
required super.handler,
|
||||
required super.wire,
|
||||
required super.generalizedFrbRustBinding,
|
||||
required super.portManager,
|
||||
});
|
||||
|
||||
@protected
|
||||
String dco_decode_String(dynamic raw);
|
||||
|
||||
@protected
|
||||
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw);
|
||||
|
||||
@protected
|
||||
void dco_decode_unit(dynamic raw);
|
||||
|
||||
@protected
|
||||
String sse_decode_String(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
void sse_decode_unit(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_i_32(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
bool sse_decode_bool(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_String(String self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_list_prim_u_8_strict(
|
||||
Uint8List self,
|
||||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_unit(void self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_i_32(int self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_bool(bool self, SseSerializer serializer);
|
||||
}
|
||||
|
||||
// Section: wire_class
|
||||
|
||||
class RustLibWire implements BaseWire {
|
||||
factory RustLibWire.fromExternalLibrary(ExternalLibrary lib) =>
|
||||
RustLibWire(lib.ffiDynamicLibrary);
|
||||
|
||||
/// Holds the symbol lookup function.
|
||||
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
|
||||
_lookup;
|
||||
|
||||
/// The symbols are looked up in [dynamicLibrary].
|
||||
RustLibWire(ffi.DynamicLibrary dynamicLibrary)
|
||||
: _lookup = dynamicLibrary.lookup;
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
// This file is automatically generated, so please do not edit it.
|
||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||
|
||||
// ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field
|
||||
|
||||
// Static analysis wrongly picks the IO variant, thus ignore this
|
||||
// ignore_for_file: argument_type_not_assignable
|
||||
|
||||
import 'api/simple.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'frb_generated.dart';
|
||||
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_web.dart';
|
||||
|
||||
abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
RustLibApiImplPlatform({
|
||||
required super.handler,
|
||||
required super.wire,
|
||||
required super.generalizedFrbRustBinding,
|
||||
required super.portManager,
|
||||
});
|
||||
|
||||
@protected
|
||||
String dco_decode_String(dynamic raw);
|
||||
|
||||
@protected
|
||||
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_8(dynamic raw);
|
||||
|
||||
@protected
|
||||
void dco_decode_unit(dynamic raw);
|
||||
|
||||
@protected
|
||||
String sse_decode_String(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_8(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
void sse_decode_unit(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_i_32(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
bool sse_decode_bool(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_String(String self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_list_prim_u_8_strict(
|
||||
Uint8List self,
|
||||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_8(int self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_unit(void self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_i_32(int self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_bool(bool self, SseSerializer serializer);
|
||||
}
|
||||
|
||||
// Section: wire_class
|
||||
|
||||
class RustLibWire implements BaseWire {
|
||||
RustLibWire.fromExternalLibrary(ExternalLibrary lib);
|
||||
}
|
||||
|
||||
@JS('wasm_bindgen')
|
||||
external RustLibWasmModule get wasmModule;
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
extension type RustLibWasmModule._(JSObject _) implements JSObject {}
|
||||
|
|
@ -7,16 +7,13 @@ cmake_minimum_required(VERSION 3.10)
|
|||
set(PROJECT_NAME "ccc_cryptography")
|
||||
project(${PROJECT_NAME} LANGUAGES CXX)
|
||||
|
||||
# Invoke the build for native code shared with the other target platforms.
|
||||
# This can be changed to accommodate different builds.
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
|
||||
include("../cargokit/cmake/cargokit.cmake")
|
||||
apply_cargokit(${PROJECT_NAME} ../rust ccc_cryptography "")
|
||||
|
||||
# List of absolute paths to libraries that should be bundled with the plugin.
|
||||
# This list could contain prebuilt libraries, or libraries created by an
|
||||
# external build triggered from this build file.
|
||||
set(ccc_cryptography_bundled_libraries
|
||||
# Defined in ../src/CMakeLists.txt.
|
||||
# This can be changed to accommodate different builds.
|
||||
$<TARGET_FILE:ccc_cryptography>
|
||||
"${${PROJECT_NAME}_cargokit_lib}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
// Relative import to be able to reuse the C sources.
|
||||
// See the comment in ../ccc_cryptography.podspec for more information.
|
||||
#include "../../src/ccc_cryptography.c"
|
||||
|
|
@ -0,0 +1 @@
|
|||
// This is an empty file to force CocoaPods to create a framework.
|
||||
|
|
@ -18,17 +18,27 @@ A new Flutter FFI plugin project.
|
|||
# paths, so Classes contains a forwarder C file that relatively imports
|
||||
# `../src/*` so that the C sources can be shared among all target platforms.
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*'
|
||||
|
||||
# If your plugin requires a privacy manifest, for example if it collects user
|
||||
# data, update the PrivacyInfo.xcprivacy file to describe your plugin's
|
||||
# privacy impact, and then uncomment this line. For more information,
|
||||
# see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
|
||||
# s.resource_bundles = {'ccc_cryptography_privacy' => ['Resources/PrivacyInfo.xcprivacy']}
|
||||
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.dependency 'FlutterMacOS'
|
||||
|
||||
s.platform = :osx, '10.11'
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
|
||||
s.swift_version = '5.0'
|
||||
end
|
||||
|
||||
s.script_phase = {
|
||||
:name => 'Build Rust library',
|
||||
# First argument is relative path to the `rust` folder, second is name of rust library
|
||||
:script => 'sh "$PODS_TARGET_SRCROOT/../cargokit/build_pod.sh" ../rust ccc_cryptography',
|
||||
:execution_position => :before_compile,
|
||||
:input_files => ['${BUILT_PRODUCTS_DIR}/cargokit_phony'],
|
||||
# Let XCode know that the static library referenced in -force_load below is
|
||||
# created by this build step.
|
||||
:output_files => ["${BUILT_PRODUCTS_DIR}/libccc_cryptography.a"],
|
||||
}
|
||||
s.pod_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
|
||||
'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/libccc_cryptography.a',
|
||||
}
|
||||
end
|
||||
10
pubspec.yaml
10
pubspec.yaml
|
|
@ -1,7 +1,7 @@
|
|||
name: ccc_cryptography
|
||||
description: "Copius Cipher Chain Cryptography"
|
||||
publish_to: 'none'
|
||||
version: 0.0.1
|
||||
homepage:
|
||||
|
||||
environment:
|
||||
sdk: ^3.10.1
|
||||
|
|
@ -11,13 +11,19 @@ dependencies:
|
|||
flutter:
|
||||
sdk: flutter
|
||||
plugin_platform_interface: ^2.0.2
|
||||
flutter_rust_bridge: 2.11.1
|
||||
freezed_annotation: ^2.4.1
|
||||
meta: ^1.11.0
|
||||
|
||||
dev_dependencies:
|
||||
ffi: ^2.1.3
|
||||
ffigen: ^13.0.0
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^6.0.0
|
||||
build_runner: ^2.4.8
|
||||
freezed: ^2.5.2
|
||||
integration_test:
|
||||
sdk: flutter
|
||||
|
||||
flutter:
|
||||
plugin:
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "ccc_cryptography"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "staticlib"]
|
||||
|
||||
[dependencies]
|
||||
# Local dev paths — switch to git deps for CI/release:
|
||||
# ccc-crypto-core = { git = "ssh://git@10.0.5.109/j3g/lum_ccc_rust.git", rev = "971f1ae" }
|
||||
# ccc-crypto-wolfssl = { git = "ssh://git@10.0.5.109/j3g/lum_ccc_rust.git", rev = "971f1ae" }
|
||||
ccc-crypto-core = { path = "/Volumes/LUM/source/letusmsg_proj/app/lum_ccc_rust/crates/ccc-crypto-core" }
|
||||
ccc-crypto-wolfssl = { path = "/Volumes/LUM/source/letusmsg_proj/app/lum_ccc_rust/crates/ccc-crypto-wolfssl" }
|
||||
flutter_rust_bridge = "=2.11.1"
|
||||
|
|
@ -0,0 +1 @@
|
|||
pub mod simple;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#[flutter_rust_bridge::frb(sync)] // Synchronous mode for simplicity of the demo
|
||||
pub fn greet(name: String) -> String {
|
||||
format!("Hello, {name}!")
|
||||
}
|
||||
|
||||
#[flutter_rust_bridge::frb(init)]
|
||||
pub fn init_app() {
|
||||
// Default utilities - feel free to customize
|
||||
flutter_rust_bridge::setup_default_user_utils();
|
||||
}
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
// This file is automatically generated, so please do not edit it.
|
||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||
|
||||
#![allow(
|
||||
non_camel_case_types,
|
||||
unused,
|
||||
non_snake_case,
|
||||
clippy::needless_return,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::redundant_closure,
|
||||
clippy::useless_conversion,
|
||||
clippy::unit_arg,
|
||||
clippy::unused_unit,
|
||||
clippy::double_parens,
|
||||
clippy::let_and_return,
|
||||
clippy::too_many_arguments,
|
||||
clippy::match_single_binding,
|
||||
clippy::clone_on_copy,
|
||||
clippy::let_unit_value,
|
||||
clippy::deref_addrof,
|
||||
clippy::explicit_auto_deref,
|
||||
clippy::borrow_deref_ref,
|
||||
clippy::needless_borrow
|
||||
)]
|
||||
|
||||
// Section: imports
|
||||
|
||||
use flutter_rust_bridge::for_generated::byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt};
|
||||
use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable};
|
||||
use flutter_rust_bridge::{Handler, IntoIntoDart};
|
||||
|
||||
// Section: boilerplate
|
||||
|
||||
flutter_rust_bridge::frb_generated_boilerplate!(
|
||||
default_stream_sink_codec = SseCodec,
|
||||
default_rust_opaque = RustOpaqueMoi,
|
||||
default_rust_auto_opaque = RustAutoOpaqueMoi,
|
||||
);
|
||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.11.1";
|
||||
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = -1918914929;
|
||||
|
||||
// Section: executor
|
||||
|
||||
flutter_rust_bridge::frb_generated_default_handler!();
|
||||
|
||||
// Section: wire_funcs
|
||||
|
||||
fn wire__crate__api__simple__greet_impl(
|
||||
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
||||
rust_vec_len_: i32,
|
||||
data_len_: i32,
|
||||
) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
|
||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::<flutter_rust_bridge::for_generated::SseCodec, _>(
|
||||
flutter_rust_bridge::for_generated::TaskInfo {
|
||||
debug_name: "greet",
|
||||
port: None,
|
||||
mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync,
|
||||
},
|
||||
move || {
|
||||
let message = unsafe {
|
||||
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
|
||||
ptr_,
|
||||
rust_vec_len_,
|
||||
data_len_,
|
||||
)
|
||||
};
|
||||
let mut deserializer =
|
||||
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
||||
let api_name = <String>::sse_decode(&mut deserializer);
|
||||
deserializer.end();
|
||||
transform_result_sse::<_, ()>((move || {
|
||||
let output_ok = Result::<_, ()>::Ok(crate::api::simple::greet(api_name))?;
|
||||
Ok(output_ok)
|
||||
})())
|
||||
},
|
||||
)
|
||||
}
|
||||
fn wire__crate__api__simple__init_app_impl(
|
||||
port_: flutter_rust_bridge::for_generated::MessagePort,
|
||||
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
||||
rust_vec_len_: i32,
|
||||
data_len_: i32,
|
||||
) {
|
||||
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec, _, _>(
|
||||
flutter_rust_bridge::for_generated::TaskInfo {
|
||||
debug_name: "init_app",
|
||||
port: Some(port_),
|
||||
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
|
||||
},
|
||||
move || {
|
||||
let message = unsafe {
|
||||
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
|
||||
ptr_,
|
||||
rust_vec_len_,
|
||||
data_len_,
|
||||
)
|
||||
};
|
||||
let mut deserializer =
|
||||
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
|
||||
deserializer.end();
|
||||
move |context| {
|
||||
transform_result_sse::<_, ()>((move || {
|
||||
let output_ok = Result::<_, ()>::Ok({
|
||||
crate::api::simple::init_app();
|
||||
})?;
|
||||
Ok(output_ok)
|
||||
})())
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Section: dart2rust
|
||||
|
||||
impl SseDecode for String {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
let mut inner = <Vec<u8>>::sse_decode(deserializer);
|
||||
return String::from_utf8(inner).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for Vec<u8> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
let mut len_ = <i32>::sse_decode(deserializer);
|
||||
let mut ans_ = vec![];
|
||||
for idx_ in 0..len_ {
|
||||
ans_.push(<u8>::sse_decode(deserializer));
|
||||
}
|
||||
return ans_;
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for u8 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
deserializer.cursor.read_u8().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for () {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {}
|
||||
}
|
||||
|
||||
impl SseDecode for i32 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
deserializer.cursor.read_i32::<NativeEndian>().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for bool {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
deserializer.cursor.read_u8().unwrap() != 0
|
||||
}
|
||||
}
|
||||
|
||||
fn pde_ffi_dispatcher_primary_impl(
|
||||
func_id: i32,
|
||||
port: flutter_rust_bridge::for_generated::MessagePort,
|
||||
ptr: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
||||
rust_vec_len: i32,
|
||||
data_len: i32,
|
||||
) {
|
||||
// Codec=Pde (Serialization + dispatch), see doc to use other codecs
|
||||
match func_id {
|
||||
2 => wire__crate__api__simple__init_app_impl(port, ptr, rust_vec_len, data_len),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn pde_ffi_dispatcher_sync_impl(
|
||||
func_id: i32,
|
||||
ptr: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
|
||||
rust_vec_len: i32,
|
||||
data_len: i32,
|
||||
) -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
|
||||
// Codec=Pde (Serialization + dispatch), see doc to use other codecs
|
||||
match func_id {
|
||||
1 => wire__crate__api__simple__greet_impl(ptr, rust_vec_len, data_len),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
// Section: rust2dart
|
||||
|
||||
impl SseEncode for String {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
<Vec<u8>>::sse_encode(self.into_bytes(), serializer);
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for Vec<u8> {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
<i32>::sse_encode(self.len() as _, serializer);
|
||||
for item in self {
|
||||
<u8>::sse_encode(item, serializer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for u8 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
serializer.cursor.write_u8(self).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for () {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
|
||||
}
|
||||
|
||||
impl SseEncode for i32 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
serializer.cursor.write_i32::<NativeEndian>(self).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for bool {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
serializer.cursor.write_u8(self as _).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
mod io {
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||
|
||||
// Section: imports
|
||||
|
||||
use super::*;
|
||||
use flutter_rust_bridge::for_generated::byteorder::{
|
||||
NativeEndian, ReadBytesExt, WriteBytesExt,
|
||||
};
|
||||
use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable};
|
||||
use flutter_rust_bridge::{Handler, IntoIntoDart};
|
||||
|
||||
// Section: boilerplate
|
||||
|
||||
flutter_rust_bridge::frb_generated_boilerplate_io!();
|
||||
}
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
pub use io::*;
|
||||
|
||||
/// cbindgen:ignore
|
||||
#[cfg(target_family = "wasm")]
|
||||
mod web {
|
||||
// This file is automatically generated, so please do not edit it.
|
||||
// @generated by `flutter_rust_bridge`@ 2.11.1.
|
||||
|
||||
// Section: imports
|
||||
|
||||
use super::*;
|
||||
use flutter_rust_bridge::for_generated::byteorder::{
|
||||
NativeEndian, ReadBytesExt, WriteBytesExt,
|
||||
};
|
||||
use flutter_rust_bridge::for_generated::wasm_bindgen;
|
||||
use flutter_rust_bridge::for_generated::wasm_bindgen::prelude::*;
|
||||
use flutter_rust_bridge::for_generated::{transform_result_dco, Lifetimeable, Lockable};
|
||||
use flutter_rust_bridge::{Handler, IntoIntoDart};
|
||||
|
||||
// Section: boilerplate
|
||||
|
||||
flutter_rust_bridge::frb_generated_boilerplate_web!();
|
||||
}
|
||||
#[cfg(target_family = "wasm")]
|
||||
pub use web::*;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
mod api;
|
||||
mod frb_generated;
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
# The Flutter tooling requires that developers have CMake 3.10 or later
|
||||
# installed. You should not increase this version, as doing so will cause
|
||||
# the plugin to fail to compile for some customers of the plugin.
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(ccc_cryptography_library VERSION 0.0.1 LANGUAGES C)
|
||||
|
||||
add_library(ccc_cryptography SHARED
|
||||
"ccc_cryptography.c"
|
||||
)
|
||||
|
||||
set_target_properties(ccc_cryptography PROPERTIES
|
||||
PUBLIC_HEADER ccc_cryptography.h
|
||||
OUTPUT_NAME "ccc_cryptography"
|
||||
)
|
||||
|
||||
target_compile_definitions(ccc_cryptography PUBLIC DART_SHARED_LIB)
|
||||
|
||||
if (ANDROID)
|
||||
# Support Android 15 16k page size
|
||||
target_link_options(ccc_cryptography PRIVATE "-Wl,-z,max-page-size=16384")
|
||||
endif()
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#include "ccc_cryptography.h"
|
||||
|
||||
// A very short-lived native function.
|
||||
//
|
||||
// For very short-lived functions, it is fine to call them on the main isolate.
|
||||
// They will block the Dart execution while running the native function, so
|
||||
// only do this for native functions which are guaranteed to be short-lived.
|
||||
FFI_PLUGIN_EXPORT int sum(int a, int b) { return a + b; }
|
||||
|
||||
// A longer-lived native function, which occupies the thread calling it.
|
||||
//
|
||||
// Do not call these kind of native functions in the main isolate. They will
|
||||
// block Dart execution. This will cause dropped frames in Flutter applications.
|
||||
// Instead, call these native functions on a separate isolate.
|
||||
FFI_PLUGIN_EXPORT int sum_long_running(int a, int b) {
|
||||
// Simulate work.
|
||||
#if _WIN32
|
||||
Sleep(5000);
|
||||
#else
|
||||
usleep(5000 * 1000);
|
||||
#endif
|
||||
return a + b;
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
#define FFI_PLUGIN_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define FFI_PLUGIN_EXPORT
|
||||
#endif
|
||||
|
||||
// A very short-lived native function.
|
||||
//
|
||||
// For very short-lived functions, it is fine to call them on the main isolate.
|
||||
// They will block the Dart execution while running the native function, so
|
||||
// only do this for native functions which are guaranteed to be short-lived.
|
||||
FFI_PLUGIN_EXPORT int sum(int a, int b);
|
||||
|
||||
// A longer lived native function, which occupies the thread calling it.
|
||||
//
|
||||
// Do not call these kind of native functions in the main isolate. They will
|
||||
// block Dart execution. This will cause dropped frames in Flutter applications.
|
||||
// Instead, call these native functions on a separate isolate.
|
||||
FFI_PLUGIN_EXPORT int sum_long_running(int a, int b);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import 'package:integration_test/integration_test_driver.dart';
|
||||
|
||||
Future<void> main() => integrationDriver();
|
||||
|
|
@ -8,16 +8,13 @@ cmake_minimum_required(VERSION 3.14)
|
|||
set(PROJECT_NAME "ccc_cryptography")
|
||||
project(${PROJECT_NAME} LANGUAGES CXX)
|
||||
|
||||
# Invoke the build for native code shared with the other target platforms.
|
||||
# This can be changed to accommodate different builds.
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../src" "${CMAKE_CURRENT_BINARY_DIR}/shared")
|
||||
include("../cargokit/cmake/cargokit.cmake")
|
||||
apply_cargokit(${PROJECT_NAME} ../rust ccc_cryptography "")
|
||||
|
||||
# List of absolute paths to libraries that should be bundled with the plugin.
|
||||
# This list could contain prebuilt libraries, or libraries created by an
|
||||
# external build triggered from this build file.
|
||||
set(ccc_cryptography_bundled_libraries
|
||||
# Defined in ../src/CMakeLists.txt.
|
||||
# This can be changed to accommodate different builds.
|
||||
$<TARGET_FILE:ccc_cryptography>
|
||||
"${${PROJECT_NAME}_cargokit_lib}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue