ActorsEnvelope

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:

content
  empty # content hash
encrypted for
  A's hash bytes
    RSA/OAEP(AES key, A's public key)
  B's hash bytes
    RSA/OAEP(AES key, B's public key)
  …
signature
  RSA/PSS(content hash, sender's private key)

The content hash points to the content object (and the tree it spans). This object is encrypted with the AES key, 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 stored as byte sequences, and do not link their public key. 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:

content
  empty # content hash
signature
  signature

The content hash points to the public card, which must reside on the same store.

Message envelopes

A message envelope in the in-queue box has the following structure:

content
  AES256CTR(content object bytes, AES key)
encrypted for
  A's hash bytes
    RSA/OAEP(AES key, A's public key)
  B's hash bytes
    RSA/OAEP(AES key, B's public key)
  …
updated by (optional)
  S's hash bytes
  T's hash bytes
  …
expires (optional)
  expiration date
signature
  RSA/PSS(SHA256(content object bytes), sender's private key)

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 stored as byte sequences, and do not link their public key. The RSA-encrypted AES keys are encoded as unsigned big-endian integers.

The updated by section lists actors entitled to remove the message from the in-queue box — usually for the purpose of updating it. This typically includes the sender.

If an expiration date is specified, the store may remove the message once it has expired.

The signature signs the content, 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:

store
  sender store URL
sender
  empty # sender hash
message content

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:

Private box Public box Card Public key Message data In-queue Message envelope Recipient's account Sender's account (and store) ... Content object

Small messages may be fully included in the content object.