User
Device

Device

A Device always belongs to a user and is used to make sure the user can access their data from multiple devices.

Why not have a single Device per user?

The main reason is to allow the user to invalidate a Device without invalidating their entire account. This is useful if a device e.g. a mobile phone is lost or stolen.

Other reasons:

  • There is no access to Secure Element on the web and in order to allow users still access through a web-interface, a Device is created for them and stored in the browser's localstorage and has an expiration date.
  • Devices also reduce the risk of a user to completely loose their data e.g. when they lose their password.

Unfortionatly this decision also comes with some downsides:

  • Need to encrypt for multiple device
  • Need to manage the authenticity of multiple devices

MainDevice

The MainDevice is only held in memory when decrypted and never stored in any kind of local storage regardless if it is a Web, mobile or desktop client.

Structure of a Device

A Device consists of a:

  • Signature Key Pair
  • Encryption Key Pair
  • Signature of the Encryption Public Key with the Signature Private Key

The purpose of the signature is to verify that

Code references:

Signature Key Pair

For the signature key pair, we use the Ed25519 algorithm which is generated using Libsodium's crypto_sign_keypair().

https://github.com/SerenityNotes/Serenity/blob/main/packages/common/src/createDevice/createDevice.ts (opens in a new tab)

Encryption Key Pair

For the encryption key pair, we use the X25519 algorithm which is generated using Libsodium's crypto_box_keypair(). The public key is then signed with the signature key pair using Libsodium's crypto_sign_detached().