on master help sign in
Remove payload versioning and schema migrations
commitfc75d8956b39674c1ab00656871f6333fc3adc17 authoriko <mail@iko.soy> dateWed 22 Apr 2026, 20:34 (6 months ago) parent56d04b5
3 files changed+19−72
client/Constants.fs−1 client/Crypto.fs+18−48 client/Store.fs+1−23
client/Constants.fs−1
@@ -10,7 +10,6 @@ module Constants =
1010 let hkdfInfo = "skrepka-v1"
1111 let profileId = "me"
1212 let settingsId = "settings"
13− let schemaVersion = 2
1413 let maxBitmapCacheSize = 128
1514 let pollRetryBaseMs = 3000
1615 let outboxRetryDelayMs = 3000
client/Crypto.fs+18−48
@@ -178,16 +178,14 @@ module Crypto =
178178 let info = Encoding.UTF8.GetBytes(Constants.hkdfInfo)
179179 HKDF.DeriveKey(HashAlgorithmName.SHA256, rawSecret, 32, salt, info)
180180
181− // Blob layout v2: [ephPub(32) | nonce(24) | ciphertext]
181+ // Blob layout: [ephPub(32) | nonce(24) | ciphertext]
182182 // encrypted payload: [senderPub(32) | signature(64) | compressed]
183183 // signature signs (recipientPub ++ compressed) — prevents forwarding
184− // Legacy layout: [ephPub(32) | nonce(24) | ciphertext | senderPub(32) | signature(64)]
185184 let private ephPubLen = 32
186185 let private nonceLen = 24
187186 let private pubLen = 32
188187 let private sigLen = 64
189188 let private headerLen = ephPubLen + nonceLen
190− let private legacyTrailerLen = pubLen + sigLen
191189 let private minBlobLen = headerLen + pubLen + sigLen + 16 // inner fields + AEAD tag
192190
193191 let private deriveSymKey recipientPrivKey ephPub =
@@ -226,50 +224,22 @@ module Crypto =
226224 else
227225 let ephPub = blob.[.. ephPubLen - 1]
228226 let nonce = blob.[ephPubLen .. headerLen - 1]
227+ let ciphertext = blob.[headerLen ..]
228+ let key = deriveSymKey recipientPrivKey ephPub
229+ let decrypted = aeadDecrypt ciphertext nonce key
229230
230− // Try v2 format: entire payload after header is ciphertext
231− let v2Result =
232− try
233− let ciphertext = blob.[headerLen ..]
234− let key = deriveSymKey recipientPrivKey ephPub
235− let decrypted = aeadDecrypt ciphertext nonce key
236−
237− if decrypted.Length < pubLen + sigLen then
238− None
239− else
240− let senderPub = decrypted.[.. pubLen - 1]
241− let signature = decrypted.[pubLen .. pubLen + sigLen - 1]
242− let compressed = decrypted.[pubLen + sigLen ..]
243−
244− let recipientPub = recipientPrivKey.[32..63]
245− let signedData = Array.append recipientPub compressed
246−
247− if verifyDetached signature signedData senderPub then
248− let plaintext = LZ4Pickler.Unpickle(compressed)
249− Some(Encoding.UTF8.GetString(plaintext), toHex senderPub)
250− else
251− None
252− with _ -> None
253−
254− match v2Result with
255− | Some _ -> v2Result
256− | None ->
257− // Fall back to legacy format: trailer has senderPub + signature in plaintext
258− try
259− if blob.Length < headerLen + 16 + legacyTrailerLen then
260− None
261− else
262− let ciphertext = blob.[headerLen .. blob.Length - legacyTrailerLen - 1]
263− let senderPub = blob.[blob.Length - legacyTrailerLen .. blob.Length - sigLen - 1]
264− let signature = blob.[blob.Length - sigLen ..]
265−
266− if not (verifyDetached signature ciphertext senderPub) then
267− None
268− else
269− let key = deriveSymKey recipientPrivKey ephPub
270− let decrypted = aeadDecrypt ciphertext nonce key
271− let plaintext = LZ4Pickler.Unpickle(decrypted)
272− Some(Encoding.UTF8.GetString(plaintext), toHex senderPub)
273− with ex ->
274− log $"decrypt error: {ex.Message}"
231+ if decrypted.Length < pubLen + sigLen then
232+ None
233+ else
234+ let senderPub = decrypted.[.. pubLen - 1]
235+ let signature = decrypted.[pubLen .. pubLen + sigLen - 1]
236+ let compressed = decrypted.[pubLen + sigLen ..]
237+
238+ let recipientPub = recipientPrivKey.[32..63]
239+ let signedData = Array.append recipientPub compressed
240+
241+ if verifyDetached signature signedData senderPub then
242+ let plaintext = LZ4Pickler.Unpickle(compressed)
243+ Some(Encoding.UTF8.GetString(plaintext), toHex senderPub)
244+ else
275245 None
client/Store.fs+1−23
@@ -137,29 +137,7 @@ module Store =
137137 |> Db.exec
138138
139139 conn
140− |> Db.newCommand "CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)"
141− |> Db.exec
142−
143− let dbVersion =
144− try
145− conn
146− |> Db.newCommand "SELECT value FROM schema_meta WHERE key = 'schema_version'"
147− |> Db.querySingle (fun rd -> rd.ReadString "value" |> int)
148− |> Option.defaultValue 0
149− with ex ->
150− log $"schema version check: {ex.Message}"
151− 0
152−
153− if dbVersion < 2 then
154− conn
155− |> Db.newCommand "CREATE INDEX IF NOT EXISTS idx_messages_conv ON messages(ConversationId)"
156− |> Db.exec
157−
158− conn
159− |> Db.newCommand "INSERT OR REPLACE INTO schema_meta (key, value) VALUES (@key, @value)"
160− |> Db.setParams
161− [ "key", SqlType.String "schema_version"
162− "value", SqlType.String(string Constants.schemaVersion) ]
140+ |> Db.newCommand "CREATE INDEX IF NOT EXISTS idx_messages_conv ON messages(ConversationId)"
163141 |> Db.exec
164142
165143 // ── Identity ──