Communications

All communications between Chapp users are automatically end-to-end encryptedopen in new window (the encryption keysopen in new window are generated and stored on the phones, not on the servers).

Generating Key Pairs

Each user in Chapp has a key pair, with their public key available in a trusted service for other users to fetch and their private keys stored securelyopen in new window on their device. For generating storing and deleting key pair we use IdentityKeyManageropen in new window.

For generating private key we use Curve25519open in new window algorithms. The public key has a var rawRepresentation: Data property, which we use to serialize it into the payload for the trusted service.

Encrypting / Decrypting Data

To encrypt data for a user we use Cryptographyopen in new window helper which uses ChaChaPolyopen in new window under the hood. ChaChaPoly can be three times faster than AES in mobile devices, according to Adam Langleyopen in new window and other researchers.

Encrypting data:
  • fetch recipient public key from the trusted service
  • initialize a Curve25519 Key for Key Agreement
let recipientPublicKey = try Curve25519.KeyAgreement.PublicKey(rawRepresentation: publicKeyRawRepresentation)
1
let sharedSecret = try senderPrivateKey.sharedSecretFromKeyAgreement(with: recipientPublicKey)
1
  • generate a symmetric key for use with software implementations of cryptographic algorithms
let symetricKey = SymmetricKey(data: sharedSecret)
1
let sealedBox = try ChaChaPoly.seal(data, using: symetricKey)
1
  • get the combined representation
let encryptedData = sealedBox.combined
1

The encryptedData can now be safely sent to our recipient.

Decrypting data:
  • fetch sender public key from the trusted service
  • initialize a Curve25519 Key for Key Agreement
let senderPublicKey = try Curve25519.KeyAgreement.PublicKey(rawRepresentation: publicKeyRawRepresentation)
1
let sharedSecretOpen = try recipientPrivateKey.sharedSecretFromKeyAgreement(with: senderPublicKey)
1
  • generate a symmetric key for use with software implementations of cryptographic algorithms
let symetricKeyOpen = SymmetricKey(data: sharedSecretOpen)
1
  • generate a secure container for your data that you access using a cipher
let box = try ChaChaPoly.SealedBox(combined: data)
1
let decryptedData = try ChaChaPoly.open(box, using: symetricKeyOpen)
1