Introduce kyber pre key triple table

This commit is contained in:
Fedor Indutny
2025-09-29 16:23:41 -07:00
committed by GitHub
parent af55cf4682
commit 658a63cfe6
8 changed files with 178 additions and 15 deletions

View File

@@ -590,6 +590,12 @@ export type MediaItemDBType = Readonly<{
message: MediaItemMessageType;
}>;
export type KyberPreKeyTripleType = Readonly<{
id: PreKeyIdType;
signedPreKeyId: number;
baseKey: Uint8Array;
}>;
export const MESSAGE_ATTACHMENT_COLUMNS = [
'messageId',
'conversationId',
@@ -956,6 +962,9 @@ type WritableInterface = {
removeKyberPreKeyById: (id: PreKeyIdType | Array<PreKeyIdType>) => number;
removeKyberPreKeysByServiceId: (serviceId: ServiceIdString) => void;
removeAllKyberPreKeys: () => number;
markKyberTripleSeenOrFail: (
options: KyberPreKeyTripleType
) => 'seen' | 'fail';
removePreKeyById: (id: PreKeyIdType | Array<PreKeyIdType>) => number;
removePreKeysByServiceId: (serviceId: ServiceIdString) => void;

View File

@@ -140,6 +140,7 @@ import type {
GetUnreadByConversationAndMarkReadResultType,
IdentityKeyIdType,
ItemKeyType,
KyberPreKeyTripleType,
MediaItemDBType,
MessageAttachmentsCursorType,
MessageCursorType,
@@ -531,6 +532,7 @@ export const DataWriter: ServerWritableInterface = {
bulkAddKyberPreKeys,
removeKyberPreKeyById,
removeKyberPreKeysByServiceId,
markKyberTripleSeenOrFail,
removeAllKyberPreKeys,
createOrUpdatePreKey,
@@ -1075,6 +1077,34 @@ function removeKyberPreKeysByServiceId(
serviceId,
});
}
function markKyberTripleSeenOrFail(
db: WritableDB,
{ id, signedPreKeyId, baseKey }: KyberPreKeyTripleType
): 'seen' | 'fail' {
// Notes that `kyberPreKey_triples` has
// - Unique constraint on id, signedPreKeyId, baseKey so that we can't insert
// two identical rows
// - `ON DELETE CASCADE` trigger linked to `kyberPreKeys` table so that we
// cleanup the triples whenever we remove the key
const [query, parameters] = sql`
INSERT OR FAIL INTO kyberPreKey_triples
(id, signedPreKeyId, baseKey)
VALUES
(${id}, ${signedPreKeyId}, ${baseKey});
`;
try {
db.prepare(query).run(parameters);
return 'seen';
} catch (error) {
if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {
return 'fail';
}
// Unexpected error
throw error;
}
}
function removeAllKyberPreKeys(db: WritableDB): number {
return removeAllFromTable(db, KYBER_PRE_KEYS_TABLE);
}

View File

@@ -0,0 +1,15 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { WritableDB } from '../Interface.js';
export default function updateToSchemaVersion1460(db: WritableDB): void {
db.exec(`
CREATE TABLE kyberPreKey_triples (
id TEXT NOT NULL REFERENCES kyberPreKeys(id) ON DELETE CASCADE,
signedPreKeyId INTEGER NOT NULL,
baseKey BLOB NOT NULL,
UNIQUE(id, signedPreKeyId, baseKey) ON CONFLICT FAIL
) STRICT;
`);
}

View File

@@ -122,6 +122,7 @@ import updateToSchemaVersion1430 from './1430-call-links-epoch-id.js';
import updateToSchemaVersion1440 from './1440-chat-folders.js';
import updateToSchemaVersion1450 from './1450-all-media.js';
import updateToSchemaVersion1460 from './1460-attachment-duration.js';
import updateToSchemaVersion1470 from './1470-kyber-triple.js';
import { DataWriter } from '../Server.js';
@@ -1601,6 +1602,7 @@ export const SCHEMA_VERSIONS: ReadonlyArray<SchemaUpdateType> = [
{ version: 1440, update: updateToSchemaVersion1440 },
{ version: 1450, update: updateToSchemaVersion1450 },
{ version: 1460, update: updateToSchemaVersion1460 },
{ version: 1470, update: updateToSchemaVersion1470 },
];
export class DBVersionFromFutureError extends Error {