Expand description
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.
The key agreement is ML-KEM-1024 in pq_pure, and ML-KEM-1024 with an ephemeral P-384 ECDH in pq_hybrid, combined with HKDF-SHA-384 over both secrets, both ciphertexts and the recipient’s key. Payloads are sealed with AES-256-GCM. A key travels as carried, ML-KEM-1024’s encapsulation key followed in pq_hybrid by a P-384 point, and is named by its id, the first 8 bytes of its SHA-384. Everything here is a pure function over aws-lc-rs; the frames that carry a sealed payload are built elsewhere.
Structs§
- Keyring
- One node identity’s KEM keys. It is safe to share between links. Showing it gives the current key id, never a key.
- Parties
- The request_id, caller and target one call’s or stream’s keys are bound to.
- Private
Key - A recipient’s KEM key pair: the ML-KEM-1024 decapsulation key and, in pq_hybrid, a P-384 scalar, with the key as carried that others seal to.
- Public
Key - A recipient’s KEM key as carried in a profile: what a caller seals to.
- Request
- What a request’s sealed payload is bound to: its routing fields.
Enums§
Constants§
- FRAME_
CALL - The frame types that name their key and AAD, as the wire’s text.
- FRAME_
ERROR - FRAME_
RESULT - FRAME_
STREAM_ OPEN - KEY_
HASH_ SIZE - The SHA-384 of a recipient’s key as carried.
- KEY_
ID_ SIZE - The bytes of a key id.
- KEY_
LIFETIME_ MS - How long a key is the current one: 24 hours.
- MAX_
ERROR_ CODE_ BYTES - An opened ERROR’s code and detail are bounded as a clear ERROR’s are, as macula_frame’s error_read/1 bounds them.
- MAX_
ERROR_ DETAIL_ BYTES - MLKEM_
CIPHERTEXT_ SIZE - An ML-KEM-1024 ciphertext.
- MLKEM_
DK_ SIZE - An ML-KEM-1024 expanded decapsulation key.
- NONCE_
SIZE - An AES-256-GCM nonce.
- RETIRED_
KEY_ KEPT_ MS - How long a replaced key still opens: 30 minutes.
- SCHEME
- The sealed map’s scheme number this module implements.
- TAG_
SIZE - The AES-256-GCM tag appended to every ciphertext.
Functions§
- call_
keys - The request and reply keys of one CALL or STREAM_OPEN.
frame_typeisFRAME_CALLorFRAME_STREAM_OPEN. - carried_
key_ size - The size of a KEM key as carried under
profile. - error_
plain - A sealed ERROR’s plaintext: cbor([code, detail]), both text, detail the empty text when there is none. A sealed ERROR carries no code or detail of its own; both travel sealed.
- is_
carried_ key_ size - Whether
lenis a carried KEM key’s size under some profile, as macula_record’s kem_key_sizes/0: an advertisement’s key is checked by size alone, whatever the reader’s profile. - key_
hash - The SHA-384 of a key as carried, which the combiner binds.
- key_id
- A carried key’s id: the first 8 bytes of its SHA-384.
- open
- The plaintext of a sealed payload, or
SealError::Refusedwhen the key, the nonce, the AAD or a single bit of it differ. - open_
error_ plain - A sealed ERROR’s opened plaintext as its code and detail. An empty detail is none.
- parse_
public_ key - The recipient key a key as carried holds in
profile: an advertisement’s kem_key, which a caller seals to. A key of another size than the profile’s, an ML-KEM key aws-lc refuses, or a P-384 point that is not an uncompressed point on the curve isSealError::Key. - random_
nonce - A fresh nonce, for a reply, a provider stream frame or an event, which carry theirs.
- recipient_
secret - The shared secret a kem_ct carries, recovered with the recipient’s own
key. A kem_ct of the wrong length for the key’s profile, an ephemeral
point that is not an uncompressed point on P-384, or a zero ECDH output
is
SealError::Refused. - reply_
aad - A RESULT’s or ERROR’s AAD: its request’s routing fields under the reply’s frame type, the request hash the reply carries and the provider that responded.
- request_
aad - A CALL’s or STREAM_OPEN’s AAD. Its nonce is 12 zero bytes: k_req seals exactly one payload.
- seal
- AES-256-GCM: the ciphertext with its 16-byte tag appended.
- sender_
secret - A fresh shared secret to
recipient, and the kem_ct that carries it: ML-KEM-1024’s ciphertext, followed by the ephemeral P-384 point in pq_hybrid. - stream_
aad - A stream frame’s AAD.
- stream_
keys - The caller-to-provider and provider-to-caller keys of one stream.
- stream_
nonce - A caller stream frame’s nonce: its seq as a 96-bit big-endian integer.
Type Aliases§
- Clock
- The clock a keyring reads, in unix milliseconds.