Envelope
Envelopes are used to sign and encrypt data. They are serialized as records, stored as objects, and placed into boxes. Each box thereby uses a slightly different envelope structure.
The order of the nodes in the record structure does not matter.
Private box envelopes
A private box envelope has the following record structure:
The content hash points to the content object (and the tree it spans). This object is encrypted with the AES key (32 bytes), and resides on the same store as the envelope.
The encrypted for section lists the actors entitled to access the content. This typically includes the sender — the actor writing the data — and the actors it entrusts. Actor hashes are shortened to 24 bytes. The RSA-encrypted AES keys are encoded as unsigned big-endian integers.
The signature signs the content, and is encoded as unsigned big-endian integer.
Public box envelopes
A public box envelope follows the same structure, but omits the encrypted for section:
The content hash points to the public card, which must reside on the same store.
Message envelopes
A message envelope in a message box has the following structure:
where
content = AES256CTR(content object bytes, AES key, 0)
The envelope embeds a small content object. Its bytes (not just the data part) are encrypted using AES 256 in CTR mode. The CTR counter starts at 0, and is incremented by 1 for each AES block (16 bytes).
The encrypted for section lists actors entitled to access the content. This typically includes the recipients, and the actors they entrust. Actor hashes are shortened to 24 bytes. The RSA-encrypted AES keys are encoded as unsigned big-endian integers.
If an expiration date is specified, the store may remove the message once it has expired.
The updated by section lists actors entitled to remove the message from the message box — usually for the purpose of updating it. This typically includes the sender.
The signature signs the encrypted content object, and is encoded as unsigned big-endian integer.
The total envelope size must not exceed 16 KiB.
Content object
The content object has the following structure:
Sender store URL and sender hash point to the sender's public key, which is used to verify the envelope's signature. The remainder is used for message content, and application-specific.
The content object should not exceed 1 KiB. It typically contains the message type, some metadata, and links to the actual message data on the sender's store. To make sure that such data remains available until the message expires, the sender links it through his private box:
Small messages may be fully included in the content object.
Stream envelopes draft
A stream envelope in a message box has the following structure:
whereby content and content hash are calculated as follows:
content = AES256CTR(content object bytes, AES key, ctr + 2) content hash = SHA256(content)
The head points to a message envelope sent earlier. The AES key from the head envelope is reused for the stream envelope.
Every envelope uses a small part of the CTR range from 0 to 2128 - 1:
- The head envelope uses the range starting at 0, and requires one count for every 16 bytes of the content object.
- A stream envelope uses the range starting at ctr, and requires 2 counts for the MAC, and one additional count for every 16 bytes of the content object.
Ranges must be non-overlapping.
The mac protects the content object from being altered. This is not a signature, however: any recipient of the head message may produce valid MACs.
The expires and updated by section on the head envelope are valid for all stream envelopes.
Recipients must keep a reference to the head envelope for as long as they wish to receive the stream. Once the head envelope vanishes, stores may refuse new stream envelopes, since they reference a head envelope that does not exist (any more) on the store.