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:
2026-03-03 23:47:40 +01:00
parent 9ab306d891
commit db46b72f58
16 changed files with 1402 additions and 80 deletions

View File

@@ -5,8 +5,25 @@ edition = "2021"
description = "Crypto primitives, MLS state machine, and hybrid post-quantum KEM for quicproquo."
license = "MIT"
[features]
default = ["native"]
# The "native" feature enables MLS (openmls), OPAQUE, Cap'n Proto, tokio, and
# filesystem-backed key storage. Disable it (--no-default-features) to compile
# the pure-crypto subset to wasm32-unknown-unknown.
native = [
"dep:openmls",
"dep:openmls_rust_crypto",
"dep:openmls_traits",
"dep:tls_codec",
"dep:opaque-ke",
"dep:bincode",
"dep:capnp",
"dep:quicproquo-proto",
"dep:tokio",
]
[dependencies]
# Crypto — classical
# Crypto — classical (always available, WASM-safe)
x25519-dalek = { workspace = true }
ed25519-dalek = { workspace = true }
sha2 = { workspace = true }
@@ -16,32 +33,34 @@ ciborium = { workspace = true }
chacha20poly1305 = { workspace = true }
zeroize = { workspace = true }
rand = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
argon2 = { workspace = true }
thiserror = { workspace = true }
# Crypto — post-quantum hybrid KEM (M7)
# Crypto — post-quantum hybrid KEM (M7) — always available, WASM-safe
ml-kem = { workspace = true }
# Crypto — OPAQUE password-authenticated key exchange
opaque-ke = { workspace = true }
argon2 = { workspace = true }
# Crypto — OPAQUE password-authenticated key exchange (native only)
opaque-ke = { workspace = true, optional = true }
# Crypto — MLS (M2)
openmls = { workspace = true }
openmls_rust_crypto = { workspace = true }
openmls_traits = { workspace = true }
tls_codec = { workspace = true }
serde = { workspace = true }
bincode = { workspace = true }
serde_json = { workspace = true }
# Crypto — MLS (M2) (native only)
openmls = { workspace = true, optional = true }
openmls_rust_crypto = { workspace = true, optional = true }
openmls_traits = { workspace = true, optional = true }
tls_codec = { workspace = true, optional = true }
bincode = { workspace = true, optional = true }
# Serialisation
capnp = { workspace = true }
quicproquo-proto = { path = "../quicproquo-proto" }
# Serialisation (native only)
capnp = { workspace = true, optional = true }
quicproquo-proto = { path = "../quicproquo-proto", optional = true }
# Async runtime
tokio = { workspace = true }
# Async runtime (native only)
tokio = { workspace = true, optional = true }
# Error handling
thiserror = { workspace = true }
# WASM: provide getrandom with js backend
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }
[lints]
workspace = true