Skip to main content

Crate macula_rust

Crate macula_rust 

Source
Expand description

Rust SDK for the macula 12 mesh: node keys (ML-DSA-87, and the LAMPS composite ML-DSA-87 + RSA-PSS-4096 in pq_hybrid), bindings and signed objects, and a station dialed over QUIC with a post-quantum key exchange.

Mobile (iOS/Android via UniFFI, macula-rust-ffi) is the flagship consumer, not the ceiling: nothing below the FFI layer is mobile-specific.

Modules§

binding
TLS and CONNECT bindings and status statements, as macula_key_bindings and macula-go make and check them. A binding ties a station’s TLS leaf, or a node’s CONNECT key, to an identity key for up to 7 days; a status statement keeps a binding in force for up to an hour. Each travels as {tbs, signature}, the signature over its label, a zero byte and the tbs bytes; a verifier checks the signature over the bytes it received first, and only then decodes them.
cbor
Deterministic CBOR encode/decode, byte-for-byte compatible with macula’s own wire codec.
frame
macula 12’s frames, as macula_frame and macula-go build and read them: the requests, replies, relay errors, publications and stream frames that carry signed objects, the control frames a pq_hybrid link neighbour-signs, the decoding rule’s payload bounds, and the length-prefixed wire codec.
handshake
macula 12’s post-quantum connection handshake, as macula_handshake and macula-go build and check it: the opener, challenge, CONNECT, HELLO and status frames (D16, D22), as CBOR bytes without the length prefix.
keystore
Overridable, per-platform secure storage for a node key.
manifest
Content manifests as macula 12’s macula_manifest builds them, byte for byte: fixed-size chunks (256 KiB by default), SHA-384 hashes, a 50-byte content id <<2, Codec, SHA-384>> (tag 2 names SHA-384, D24; codec 0x55 a raw block, 0x56 a manifest), and a Merkle fold that pairs an odd last hash with itself.
node_key
A macula 12 node’s keys, as macula and macula-go hold them: ML-DSA-87 in pq_pure, and in pq_hybrid the LAMPS composite id-MLDSA87-RSA4096-PSS-SHA512 (draft-ietf-lamps-pq-composite-sigs), which signs with both halves and is valid only when both verify. An identity key’s node_id (D5) solves the admission puzzle; a CONNECT key is bound to it (see crate::binding). Keys are stored in macula’s seed form, readable by their owner only (see NodeKey::save and NodeKey::load).
petname
Petnames: a deterministic, human-readable label for a mesh node id — Docker’s adjective_color_animal convention with a four-digit suffix (e.g. “happy_green_rabbit_4831”) — so a person skimming a roster, transcript, or room listing can recognize and remember a specific identity without reading 64 hex characters. A pure function of the node id itself, not random per process: the same identity gets the same petname across restarts, across every tool that shows it, and on every other agent’s own roster too (everyone hashes the same public bytes). This is a companion label, never a replacement — every surface that adds one keeps the real node_id right alongside it, since only the real id is addressable.
pool
A macula 12 node’s set of station links, as macula’s client pool keeps them: one link to each seed station, every seed pinned by its node_id, all links of one node sharing its identity key, statement issuer, request admission, publication seq and event dedup. A link that ends is dialed again after the respawn delay and given back the node’s subscriptions and served procedures.
profile
The post-quantum crypto profile a node runs, the counterpart of macula’s macula_crypto_profile and macula-go’s profile. A realm runs one profile and every node in it is configured with that one: there is no default, no negotiation and no classical fallback.
record
macula 12’s DHT records, as macula_record and macula-go sign and verify them. A record is the signed object {key, tbs, signature} under MACULA-PQ-RECORD-V1; its tbs holds type, alg, version, created_at, expires_at and payload, and subject only on a domain type (tags 0x20 to 0xFF). sign refuses a key whose purpose does not fit the type; verify reads a record’s wire form in the design’s order and keeps its tbs bytes, so encode sends them unchanged.
seal
End-to-end payload sealing, scheme 1 (macula 13, E2E design and amendment A1): what a node needs to seal a payload so that the stations relaying it cannot read it, the counterpart of macula’s macula_seal and macula-go’s seal. The byte-exact construction is macula’s test/vectors/E2E_SEAL_V1.md, and tests/vectors/seal/e2e_seal_v1.json holds its vectors.
signed_object
Signed objects, as macula_signed_object and macula-go sign and verify them: a record, a request, a reply, a relay error, a publication, or a stream frame. The fields gain alg, the signer’s profile algorithm, and are encoded as tbs in the deterministic form; the signature covers the label, a zero byte, the SHA-384 of the signer’s key as carried, and tbs. An Object carries its key; a HeldObject leaves it out for a verifier that already holds it, and still signs its hash.
statement_issuer
A client’s status statement issuer, the client side of macula’s macula_statement_issuer (D22), as macula-go’s StatementIssuer. It holds the identity key, the node’s CONNECT bindings with the newest status statement for each, and the current CONNECT key. Each tick issues a statement valid for an hour for each binding whose not_after has not passed, and hands it to that binding’s subscribers, the links that connected with it. Every 5 days it rotates the CONNECT key: the new key’s binding and statement exist before StatementIssuer::connect_material hands the key out, and the rotated-out binding keeps its statements until its not_after. connect_material does work that is due itself, so a dial after missed ticks, a sleep or a clock step still carries material in force. Nothing is written to disk, so a new issuer starts with a new CONNECT key.
station_link
A client’s link to one macula station, as macula_station_link and macula-go’s stationlink are: a QUIC connection dialed to the station its target pins, one bidirectional control stream, the connection handshake on it (v5, or v4 once after a station refuses v5), then status statements both ways and every frame of the session.
transport
Dialing a macula 12 station over QUIC, as macula-go’s transport does.