crypto/payload_encryption library
Payload encryption compatible with the Go client's bound NaCl box
(go-ricochet pkg/client/encryption.go).
Wire format sent: "RCE2" ‖ 24-byte nonce ‖ box(header ‖ payload), where
the box is NaCl box (X25519 agreement between the two identity keys,
XSalsa20-Poly1305) and the header is the PayloadBinding as three
big-endian u16-length-prefixed fields. The binding ties the ciphertext to
the message that carries it, so a ciphertext the server moved to another
folder, or presented under another id or to another recipient, is
refused on decrypt. The legacy unbound format (nonce ‖ box(payload)),
which old Go clients sent, still opens and is reported as unbound.
What this layer is not: it has no forward secrecy (one static key pair per identity, by design; a ratchet belongs above it, as OverNode's Signal sessions are) and it does not detect a replay of the same ciphertext into the same folder.
Classes
- DecryptedPayload
-
A decrypted payload and whether its ciphertext carried a binding. A
caller that wants the replay protection should treat
bound == falseas a downgrade. - PayloadBinding
- What a ciphertext is tied to: the message it must arrive as.
- PayloadEncryptor
- Seals and opens payloads with one identity's key.
Constants
-
boundMagic
→ const List<
int> - The four bytes that open a bound ciphertext.
Functions
-
ed25519PublicKeyToX25519(
Uint8List edPublic) → Uint8List - Converts an Ed25519 public key to X25519 by the birational map from Edwards to Montgomery form, as the Go client does.
-
ed25519SeedToX25519(
Uint8List seed) → Uint8List - Converts an Ed25519 seed (the 32-byte private key) to the X25519 secret the Go client derives: SHA-512 of the seed, first 32 bytes, clamped.
-
openIfEncrypted(
SFMessage message, PayloadEncryptor? encryptor) → Future< SFMessage> -
Returns
messagewith its payload opened when it is flagged encrypted, checked against the envelope it arrived in; otherwise unchanged. -
peerIdToX25519PublicKey(
PeerId id) → Future< Uint8List> - The X25519 public key of a peer, from the Ed25519 key its id embeds.
Exceptions / Errors
- BoundToAnotherMessageException
- The ciphertext opened, but it was sealed for a different message.
- PayloadDecryptException
- Decryption failed at the Ricochet payload layer, as opposed to any end-to-end layer an application runs above it.