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
  first 24 bytes of A's hash
    RSA/OAEP(AES key, A's public key)
  first 24 bytes of B's hash
    RSA/OAEP(AES key, B's public key)
  …
signature
  RSA/PSS(content hash, owner's private key)

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:

content
  empty # content hash
signature
  RSA/PSS(content hash, owner's private key)

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:

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

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:

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 Message box Message envelope Recipient's account Sender's account (and store) ... Content object

Small messages may be fully included in the content object.

Stream envelopes draft

A stream envelope in a message box has the following structure:

content
  content
ctr
  ctr
head
  empty # head message hash
mac
  AES256CTR(content hash, AES key, ctr)

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:

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.