/metadata: the size it keeps is exact, not approximate (relay#59) #151
@@ -29,7 +29,7 @@
|
||||
<thead><tr><th>Kept</th><th>Why it has to be</th><th>Gone after</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>Recipient account and device</td><td>An envelope cannot be delivered without an address</td><td>#if(retention.deleteOnAck):the moment your app confirms receipt#else:#(retention.deliveredDays) day(s) once delivered#endif</td></tr>
|
||||
<tr><td>Arrival time and approximate size</td><td>Ordering, and the size is the ciphertext itself</td><td>#if(retention.deleteOnAck):the moment your app confirms receipt#else:#(retention.deliveredDays) day(s) once delivered#endif</td></tr>
|
||||
<tr><td>Arrival time and <strong>exact size</strong></td><td>Ordering, and the size is the ciphertext itself — so the length of a message is <strong>not</strong> hidden, to the byte. Sizes group by kind: a read receipt is not the size of a photo, and a one-word reply is not the size of a paragraph. Nothing has to be decrypted to see that, and it is a weak but real guess about what an envelope carries. Hiding it means padding messages on the sending device before they are encrypted — a change to the apps rather than to this server, because the server cannot pad what it must not read. It has not been made yet.</td><td>#if(retention.deleteOnAck):the moment your app confirms receipt#else:#(retention.deliveredDays) day(s) once delivered#endif</td></tr>
|
||||
<tr><td>Sender account and device</td><td>Identified sends only — a <strong>sealed</strong> send stores neither</td><td>#if(retention.deleteOnAck):the moment your app confirms receipt#else:#(retention.deliveredDays) day(s) once delivered#endif</td></tr>
|
||||
<tr><td>The ciphertext</td><td>It is the message; the server holds no key that opens it</td><td>#(retention.undeliveredDays) days if never collected</td></tr>
|
||||
<tr><td>Attachment blobs (photos, voice notes, stories — all ciphertext)</td><td>Devices fetch them separately from the envelope that references them</td><td>#(retention.attachmentDays) days</td></tr>
|
||||
|
||||
@@ -213,6 +213,21 @@ final class PublicPagesTests: XCTestCase {
|
||||
XCTAssertEqual(offenders, [], "\n" + offenders.joined(separator: "\n"))
|
||||
}
|
||||
|
||||
/// ⚠️ **The transparency page has to be accurate in the unflattering
|
||||
/// direction too.** `/metadata` called what it stores the "approximate
|
||||
/// size" of a message. It is not approximate: the ciphertext length is
|
||||
/// exact, and lengths group by kind, so a byte count is a weak guess about
|
||||
/// what an envelope carries (relay#59). A page that undersells what it
|
||||
/// keeps is worse than one that keeps more and says so.
|
||||
func testMetadataDoesNotUndersellWhatItKeeps() throws {
|
||||
let page = try String(contentsOf: views.appendingPathComponent("metadata.leaf"),
|
||||
encoding: .utf8)
|
||||
XCTAssertFalse(page.localizedCaseInsensitiveContains("approximate size"),
|
||||
"the stored ciphertext length is exact, not approximate")
|
||||
XCTAssertTrue(page.localizedCaseInsensitiveContains("exact size"),
|
||||
"the page no longer states that the size it keeps is exact")
|
||||
}
|
||||
|
||||
func testTheSafetyPageCarriesAReachableContact() throws {
|
||||
let page = try String(contentsOf: views.appendingPathComponent("safety.leaf"),
|
||||
encoding: .utf8)
|
||||
|
||||
Reference in New Issue
Block a user