feat: Sprint 3 — C FFI bindings, WASM compilation, Python example, SDK docs
- Create quicproquo-ffi crate with 7 extern "C" functions: connect, login, send, receive, disconnect, last_error, free_string (produces libquicproquo_ffi.so and .a) - Feature-gate quicproquo-core for WASM: identity, hybrid_kem, safety_numbers, sealed_sender, app_message, padding, transcript all compile to wasm32-unknown-unknown - Add Python ctypes example (examples/python/qpq_client.py) with QpqClient wrapper class and CLI - Add SDK documentation: FFI reference, WASM guide, qpq-gen generators - Update Dockerfile for quicproquo-ffi workspace member
This commit is contained in:
@@ -6,6 +6,7 @@ use thiserror::Error;
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CoreError {
|
||||
/// Cap'n Proto serialisation or deserialisation failed.
|
||||
#[cfg(feature = "native")]
|
||||
#[error("Cap'n Proto error: {0}")]
|
||||
Capnp(#[from] capnp::Error),
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
//! collision-resistant identifier for logging.
|
||||
|
||||
use ed25519_dalek::{Signer as DalekSigner, SigningKey, VerifyingKey};
|
||||
use openmls_traits::signatures::Signer;
|
||||
use openmls_traits::types::{Error as MlsError, SignatureScheme};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use zeroize::Zeroizing;
|
||||
@@ -87,15 +85,16 @@ impl IdentityKeypair {
|
||||
/// Implement the openmls `Signer` trait so `IdentityKeypair` can be passed
|
||||
/// directly to `KeyPackage::builder().build(...)` without needing the external
|
||||
/// `openmls_basic_credential` crate.
|
||||
impl Signer for IdentityKeypair {
|
||||
fn sign(&self, payload: &[u8]) -> Result<Vec<u8>, MlsError> {
|
||||
#[cfg(feature = "native")]
|
||||
impl openmls_traits::signatures::Signer for IdentityKeypair {
|
||||
fn sign(&self, payload: &[u8]) -> Result<Vec<u8>, openmls_traits::types::Error> {
|
||||
let sk = self.signing_key();
|
||||
let sig: ed25519_dalek::Signature = sk.sign(payload);
|
||||
Ok(sig.to_bytes().to_vec())
|
||||
}
|
||||
|
||||
fn signature_scheme(&self) -> SignatureScheme {
|
||||
SignatureScheme::ED25519
|
||||
fn signature_scheme(&self) -> openmls_traits::types::SignatureScheme {
|
||||
openmls_traits::types::SignatureScheme::ED25519
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
//! Core cryptographic primitives, MLS group state machine, and hybrid
|
||||
//! post-quantum KEM for quicproquo.
|
||||
//!
|
||||
//! # WASM support
|
||||
//!
|
||||
//! When compiled with `--no-default-features` (disabling the `native` feature),
|
||||
//! the following modules are available for `wasm32-unknown-unknown`:
|
||||
//!
|
||||
//! - `identity` — Ed25519 identity keypair (generate, sign, verify)
|
||||
//! - `hybrid_kem` — X25519 + ML-KEM-768 hybrid key encapsulation
|
||||
//! - `safety_numbers` — Signal-style safety number computation
|
||||
//! - `sealed_sender` — sender identity + Ed25519 signature envelope
|
||||
//! - `app_message` — rich application message serialisation/parsing
|
||||
//! - `padding` — message padding to hide plaintext lengths
|
||||
//! - `transcript` — encrypted tamper-evident message transcript
|
||||
//! - `error` — `CoreError` type
|
||||
//!
|
||||
//! The following modules require the `native` feature (MLS, OPAQUE, Cap'n Proto):
|
||||
//!
|
||||
//! - `group` — MLS group state machine (openmls)
|
||||
//! - `keypackage` — MLS KeyPackage generation
|
||||
//! - `hybrid_crypto` — hybrid HPKE provider for OpenMLS
|
||||
//! - `keystore` — OpenMLS key store with optional disk persistence
|
||||
//! - `opaque_auth` — OPAQUE cipher suite configuration
|
||||
//!
|
||||
//! # Module layout
|
||||
//!
|
||||
//! | Module | Responsibility |
|
||||
@@ -15,36 +37,50 @@
|
||||
|
||||
mod app_message;
|
||||
mod error;
|
||||
mod group;
|
||||
mod hybrid_crypto;
|
||||
mod hybrid_kem;
|
||||
mod identity;
|
||||
mod keypackage;
|
||||
mod keystore;
|
||||
pub mod opaque_auth;
|
||||
pub mod padding;
|
||||
pub mod safety_numbers;
|
||||
pub mod sealed_sender;
|
||||
pub mod transcript;
|
||||
|
||||
// ── Public API ────────────────────────────────────────────────────────────────
|
||||
// ── Native-only modules (MLS, OPAQUE, filesystem) ───────────────────────────
|
||||
#[cfg(feature = "native")]
|
||||
mod group;
|
||||
#[cfg(feature = "native")]
|
||||
mod hybrid_crypto;
|
||||
#[cfg(feature = "native")]
|
||||
mod keypackage;
|
||||
#[cfg(feature = "native")]
|
||||
mod keystore;
|
||||
#[cfg(feature = "native")]
|
||||
pub mod opaque_auth;
|
||||
|
||||
// ── Public API (always available) ───────────────────────────────────────────
|
||||
|
||||
pub use app_message::{
|
||||
serialize, serialize_chat, serialize_reaction, serialize_read_receipt, serialize_reply,
|
||||
serialize_typing, parse, generate_message_id, AppMessage, MessageType, VERSION as APP_MESSAGE_VERSION,
|
||||
};
|
||||
pub use error::CoreError;
|
||||
pub use group::{GroupMember, ReceivedMessage, ReceivedMessageWithSender};
|
||||
pub use hybrid_kem::{
|
||||
hybrid_decrypt, hybrid_encrypt, HybridKemError, HybridKeypair, HybridKeypairBytes,
|
||||
HybridPublicKey,
|
||||
};
|
||||
pub use hybrid_crypto::{HybridCrypto, HybridCryptoProvider};
|
||||
pub use identity::{verify_delivery_proof, IdentityKeypair};
|
||||
pub use keypackage::{generate_key_package, validate_keypackage_ciphersuite};
|
||||
pub use keystore::DiskKeyStore;
|
||||
pub use safety_numbers::compute_safety_number;
|
||||
pub use transcript::{
|
||||
read_transcript, verify_transcript_chain, ChainVerdict, DecodedRecord, TranscriptRecord,
|
||||
TranscriptWriter,
|
||||
};
|
||||
|
||||
// ── Public API (native only) ────────────────────────────────────────────────
|
||||
|
||||
#[cfg(feature = "native")]
|
||||
pub use group::{GroupMember, ReceivedMessage, ReceivedMessageWithSender};
|
||||
#[cfg(feature = "native")]
|
||||
pub use hybrid_crypto::{HybridCrypto, HybridCryptoProvider};
|
||||
#[cfg(feature = "native")]
|
||||
pub use keypackage::{generate_key_package, validate_keypackage_ciphersuite};
|
||||
#[cfg(feature = "native")]
|
||||
pub use keystore::DiskKeyStore;
|
||||
|
||||
Reference in New Issue
Block a user