Skip to main content

Module seal

Module seal 

Source
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.
PrivateKey
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.
PublicKey
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§

Direction
Which way a stream frame travels.
SealError
Why a seal operation failed.

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_type is FRAME_CALL or FRAME_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 len is 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::Refused when 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 is SealError::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.