The order of the nodes in the record structure does not matter.
Private box envelopes
A private box envelope has the following record structure:
signed content empty # content hash encrypted key recipient hash 1 RSA/OAEP(public key 1, AES key) recipient hash 2 RSA/OAEP(public key 2, AES key) … signature signature
The content hash points to the content object (and the tree it spans). This object must be encrypted, and reside on the same store as the envelope.
The AES key of the content object is RSA/OAEP encrypted for all recipients, and stored as unsigned big-endian integer. Recipient hashes are stored as byte sequences, and do not link the recipient's public key.
Public box envelopes
A public box envelope follows the same structure, but – since the content is not encrypted – omits the encrypted key section:
signed content empty # content hash signature signature
The content hash points to the public card, and the account hash points to the public key of the account holder. Content and public key are always on the same store as the envelope.
A message envelope has the following structure:
signed store store URL sender sender hash content content hash encrypted key recipient hash 1 RSA/OAEP(public key 1, AES key) recipient hash 2 RSA/OAEP(public key 2, AES key) … signature signature
The store URL indicates the sender's store holding the sender's public key (sender hash) and the encrypted message content (content hash).
The sender hash and the content hash are stored as byte sequences, since they point to objects on the sender's store, and do not link any object on the recipient's store. The sender must link this data on his store to protect it from disappearing:
The recipient list has the same structure as in private box envelopes. Note that this list is not signed, which allows recipients to re-encrypt messages for other actors while keeping the original sender and its signature.
Small messages may be included in the envelope:
signed store store URL sender sender hash encrypted key recipient hash 1 RSA/OAEP(public key 1, AES key) recipient hash 2 RSA/OAEP(public key 2, AES key) … signature signature
In place of a content hash, the encrypted message object is placed in the signed section. All other fields remain the same.
Since message envelopes are limited to 16 kiB, message inlining is allowed for small messages only, such as status updates. Inlined messages may contain references to additional content on the sender's store.
The signature field of all envelopes is generated as follows:
For private and public box envelopes, the sender (originator) is implicitly given by the account on which the envelope resides.
The resulting RSA/PSS signature is stored as unsigned big-endian integer.
An application may add hints to the signed section which may allow the recipient classify messages before retrieving their content.
Hints should be kept short, as message envelopes are limited to 16 kiB.
Hints may be encrypted using the AES key provided by the envelope, and a large CTR start value (e.g. 0x8000 0000 0000 0000).