Concepts Specifications API Downloads


Condensation is a complete data system. It can

Condensation thereby follows a distributed actor-message-passing approach, and encrypts all data end-to-end.


In Condensation, data is stored as trees of objects. An object consists of a list of hashes pointing to other objects, and a sequence of bytes:

H Data (byte sequence) Hash list (H ⨯ 32 bytes) typically 2 KiB to 20 MiB, theoretically up to 2⁶⁴ bytes

H denotes the number of hashes preceding the data. The data part often holds a record, and is usually encrypted.

Objects are identified by their SHA-256 hash (32 bytes):

Object hash ⇐ SHA-256 of

Objects are inherently immutable. Changing an object's content yields a different hash, and therefore makes it a different object.


Through the hash list, an object may span a tree:


Trees can be arbitrarily large, and may form blockchains, binary search trees, or other data structures.

Naturally, the object hash also serves as identifier for the tree it spans.

Modifying data

Since trees are immutable, they cannot be modified directly. To modify data, a new tree is derived from the current tree:

3ebfda... 513289...

If the tree is structured wisely, a large part of the old tree's data can be reused in the new tree. This yields efficient data modification, and efficient versioning.

Several modifications can be applied at the same time, leading to the equivalent of a database transaction.


Remembering a tree hash is enough to refer to an arbitrary amount of data. Hence – besides storing objects – an actor (user) just needs to manage a few hashes to keep, publish, and share data. For that, each actor owns an account with three boxes. Each box keeps a set of hashes:

public box private box in-queue box

In contrast to objects and trees, boxes are mutable. Hashes can be added and removed.


Objects and accounts are kept on a Condensation store:

put object get object list add ... remove

The object store is basically a large hash table. It stores the bulk of the data, but has a very simple structure. The account store has a slightly more complex structure, but only deals with 32-byte hashes.

A Condensation store can be accessed through 5 functions:

RSA keys

Condensation uses end-to-end encryption. Public data is signed, while private data and messages are are encrypted and signed by the actor producing that data.

For that, each actor generates a RSA 2048 key pair:

Private key Public key e p q e n

While the private key is kept in a safe place on the device, the public key is serialized as object and uploaded onto all stores the actor uses. The hash of the public key object serves as unique identifier of the actor and its accounts.

Object encryption

Condensation objects may be symmetrically encrypted as follows:

H Hashes (H ⨯ 32 bytes) encrypted not encrypted Encrypted data

The data section is thereby encrypted using AES 256 in CTR mode with a random 256-bit key. The CTR counter starts at 0, and is incremented by 1 for each AES block (16 bytes). The last block may be truncated.

The hash list remains unencrypted, so that stores can determine which objects are in use.

Tree encryption and signing

Trees are encrypted and signed as follows:

Hashes Corresponding AES keys Hash Sender signature AES key encrypted for recipients Store ... ...

The root object is an envelope with a content hash and a corresponding AES key encrypted for each recipient actor. In addition, envelopes contain the sender's signature of the content hash, and – if the content is located elsewhere – a store URL.

All objects below the root store the AES keys of their children within the encrypted data part.

Hence, any recipient can parse the envelope, verify its signature, decrypt the AES key of the content object, and then work its way down to read the whole tree.

Announcing the public card

On each account, an actor publishes and updates public information:

Envelope Public card Public key Account list and other public information public box Signature only

The public card is a record containing the accounts that the actor uses, and optionally other public information. A person may publish their name and profession — just like they would do on a business card — and a shop may even link a tree with their product list.

The account list is used by other actors to send messages. Hence, only publicly accessible accounts are published here. Internal accounts on some local storage system are not published. Each account may be marked active or idle with a revision date. Other actors will generally send messages to the newest active account.

The public card links the actors's public key to ensure that the latter does not get removed from the store.

To update the public card, the actor creates a new tree and adds it to the public box before removing the old tree. For a

Sending a message

To send a message, an actor (sender) prepares a message tree:

Envelope Message Record Signed by sender, encrypted for recipient(s),indicating sender's store ...

By convention, the main message object is an encrypted record. The message content is entirely application-dependent.

The actual message tree is uploaded onto a publicly accessible store of the sender, while the envelope is submitted to the recipient's in-queue:

private box Sender's store in-queue box Recipient's store

To prevent the message data from being garbage collected, it is attached to the sender's private data for some time.

Updating a message

The sender, or any recipient may remove a message from the in-queue. To share some data, for example, a sender may posts a first message, and replace it whenever the data changes:

private box Sender's store in-queue box Recipient's store

The actual data is tranferred only when the recipient reads the message, rendering data sharing very efficient.

Reading messages

An actor reads messages by listing its in-queue(s), and processing message by message.

For each message, the actor first downloads the envelope from its own store, verifies the signature and the indicated store, and decrypts the AES key. If anything goes wrong, the message is silently discarded. Depending on the application, an actor may allow messages from known senders or known stores only.

The actor then downloads the actual message object(s) from the sender's store, and merges the received information into his private data. Once the private data has been saved, the message is removed from the in-queue.

Private data

An actor's private data is an encrypted tree of forward-moving data, such as a data tree, attached to the private box.

private box Envelope Private data Forward-mergeable Signed by actor,encrypted for actor ...

The envelope has the same structure as a message envelope, except that sender and receiver are the same.

To modify that data (e.g. while processing messages), the actor merges (⊗) all information, constructs a new tree, and adds it to the private box:

private box in-queue box A U V B A U V B

The actor now temporarily has two versions of the data. When merged, they would yield the newer version:

A ⊗ B = B and A ⊗ B ⊗ U ⊗ V = B

Hence, the old version and the messages can be removed:

private box in-queue box

Entrusted actors

An actor may entrust other actors. Entrusted actors have full read access to all data of the actor. This is achieved by adding the entrusted actor as recipient to all envelopes. Entrusted accounts are published on the public card.

Actor groups

Actors may join to form a group. Within such a group, actors unconditionally share their private data, and can read each other's messages. A lonely actor can be regarded as a group with one actor.

Every actor of the group announces the other group members on this public card, and encrypts its private data for all members. Actors usually first read their own private data and messages, and then merge the private data and messages of other groups members.

When sending a message to a group, the actor reads all public cards (actor group discovery), encrypts the message for all groups members, and posts it on the in-queue of the most recent account.

With actor groups, a user can use the same data on multiple devices. Each device uses its own RSA key pair and accounts, potentially on different stores.

In addition, actor groups may rotate their keys regularly by creating and adding a new actor (key pair), and removing an existing one.


Actors often use two stores: