mirror of
https://github.com/signalapp/libsignal.git
synced 2026-05-09 00:22:31 +02:00
The app-visible change is that sealedSenderMultiRecipientEncrypt now takes a SessionStore as well. Sessions will be looked up in bulk using a new SessionStore API, 'loadExistingSessions' or 'getExistingSessions`. The registration ID is then loaded from each session and included in the resulting SSv2 payload. The implementation is a bit of a divergence from some other APIs in libsignal-client in that the "look up in bulk" step is performed in the Java, Swift, or TypeScript layer, with the resulting sessions passed down to Rust. Why? Because otherwise we'd pass a list of addresses into Rust, which would have to turn them back into a Java, Swift, or TypeScript array to call the SessionStore method. This would be (1) a bunch of extra work to implement, and (2) a waste of CPU when we already /have/ a list of addresses in the correct format: the argument to sealedSenderMultiRecipientEncrypt. This is an example of "the boundaries between the Rust and Java/Swift/TypeScript parts of the library don't have to be perfect; they're internal to the overall product". In this case, we've taken that a little further than usual: usually we try to make the libsignal-protocol API as convenient as possible as well, but here it had to be a bit lower-level to satisfy the needs of the app language wrappers. (Specifically, callers need to fetch the list of SessionRecords themselves.) P.S. Why doesn't v1 of sealed sender include registration IDs? Because for SSv1, libsignal-client isn't producing the entire request body to upload to the server; it's only producing the message content that will be decrypted by the recipient. With SSv2, the serialized message the recipient downloads has both shared and per-recipient data in it, which the server must assemble from the uploaded request. Because of this, SSv2's encrypt API might as well produce the entire request.