first poc works

This commit is contained in:
otsmr 2026-08-03 23:16:02 +02:00
parent 3345a2a297
commit 7e6bfa49ea
54 changed files with 19567 additions and 491 deletions

View file

@ -0,0 +1,57 @@
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.12.0.
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
import '../../frb_generated.dart';
import '../../signal/engine.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
class RustSignal {
const RustSignal();
static Future<Uint8List> decrypt({
required String name,
required int deviceId,
required List<int> ciphertext,
}) => RustLib.instance.api.crateBridgeWrapperSignalRustSignalDecrypt(
name: name,
deviceId: deviceId,
ciphertext: ciphertext,
);
static Future<Uint8List> encrypt({
required String name,
required int deviceId,
required List<int> plaintext,
}) => RustLib.instance.api.crateBridgeWrapperSignalRustSignalEncrypt(
name: name,
deviceId: deviceId,
plaintext: plaintext,
);
static Future<FrbPreKeyBundle> generateBundle() =>
RustLib.instance.api.crateBridgeWrapperSignalRustSignalGenerateBundle();
static Future<List<FrbPqcPreKey>> generatePqcPrekeys() => RustLib.instance.api
.crateBridgeWrapperSignalRustSignalGeneratePqcPrekeys();
static Future<void> processPrekeyBundle({
required String name,
required int deviceId,
required FrbPreKeyBundle bundle,
}) => RustLib.instance.api
.crateBridgeWrapperSignalRustSignalProcessPrekeyBundle(
name: name,
deviceId: deviceId,
bundle: bundle,
);
@override
int get hashCode => 0;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is RustSignal && runtimeType == other.runtimeType;
}

View file

@ -9,6 +9,7 @@ import 'bridge/callbacks/user_discovery.dart';
import 'bridge/wrapper.dart';
import 'bridge/wrapper/backup.dart';
import 'bridge/wrapper/key_manager.dart';
import 'bridge/wrapper/signal.dart';
import 'bridge/wrapper/user_discovery.dart';
import 'dart:async';
import 'dart:convert';
@ -18,6 +19,7 @@ import 'frb_generated.io.dart'
import 'keys/backup_password_keys.dart';
import 'lib.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'signal/engine.dart';
/// Main entrypoint of the Rust API
class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
@ -76,7 +78,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
String get codegenVersion => '2.12.0';
@override
int get rustContentHash => 1788847092;
int get rustContentHash => 1109927244;
static const kDefaultExternalLibraryLoaderConfig =
ExternalLibraryLoaderConfig(
@ -259,6 +261,29 @@ abstract class RustLibApi extends BaseApi {
required List<int> record,
});
Future<Uint8List> crateBridgeWrapperSignalRustSignalDecrypt({
required String name,
required int deviceId,
required List<int> ciphertext,
});
Future<Uint8List> crateBridgeWrapperSignalRustSignalEncrypt({
required String name,
required int deviceId,
required List<int> plaintext,
});
Future<FrbPreKeyBundle> crateBridgeWrapperSignalRustSignalGenerateBundle();
Future<List<FrbPqcPreKey>>
crateBridgeWrapperSignalRustSignalGeneratePqcPrekeys();
Future<void> crateBridgeWrapperSignalRustSignalProcessPrekeyBundle({
required String name,
required int deviceId,
required FrbPreKeyBundle bundle,
});
Future<List<Uint8List>> crateBridgeWrapperRustUtilsGenerateShares({
required List<int> secret,
required int total,
@ -1651,6 +1676,183 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["signedPreKeyId", "record"],
);
@override
Future<Uint8List> crateBridgeWrapperSignalRustSignalDecrypt({
required String name,
required int deviceId,
required List<int> ciphertext,
}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_String(name, serializer);
sse_encode_u_32(deviceId, serializer);
sse_encode_list_prim_u_8_loose(ciphertext, serializer);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 32,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_list_prim_u_8_strict,
decodeErrorData: sse_decode_AnyhowException,
),
constMeta: kCrateBridgeWrapperSignalRustSignalDecryptConstMeta,
argValues: [name, deviceId, ciphertext],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateBridgeWrapperSignalRustSignalDecryptConstMeta =>
const TaskConstMeta(
debugName: "rust_signal_decrypt",
argNames: ["name", "deviceId", "ciphertext"],
);
@override
Future<Uint8List> crateBridgeWrapperSignalRustSignalEncrypt({
required String name,
required int deviceId,
required List<int> plaintext,
}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_String(name, serializer);
sse_encode_u_32(deviceId, serializer);
sse_encode_list_prim_u_8_loose(plaintext, serializer);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 33,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_list_prim_u_8_strict,
decodeErrorData: sse_decode_AnyhowException,
),
constMeta: kCrateBridgeWrapperSignalRustSignalEncryptConstMeta,
argValues: [name, deviceId, plaintext],
apiImpl: this,
),
);
}
TaskConstMeta get kCrateBridgeWrapperSignalRustSignalEncryptConstMeta =>
const TaskConstMeta(
debugName: "rust_signal_encrypt",
argNames: ["name", "deviceId", "plaintext"],
);
@override
Future<FrbPreKeyBundle> crateBridgeWrapperSignalRustSignalGenerateBundle() {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 34,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_frb_pre_key_bundle,
decodeErrorData: sse_decode_AnyhowException,
),
constMeta: kCrateBridgeWrapperSignalRustSignalGenerateBundleConstMeta,
argValues: [],
apiImpl: this,
),
);
}
TaskConstMeta
get kCrateBridgeWrapperSignalRustSignalGenerateBundleConstMeta =>
const TaskConstMeta(
debugName: "rust_signal_generate_bundle",
argNames: [],
);
@override
Future<List<FrbPqcPreKey>>
crateBridgeWrapperSignalRustSignalGeneratePqcPrekeys() {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 35,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_list_frb_pqc_pre_key,
decodeErrorData: sse_decode_AnyhowException,
),
constMeta:
kCrateBridgeWrapperSignalRustSignalGeneratePqcPrekeysConstMeta,
argValues: [],
apiImpl: this,
),
);
}
TaskConstMeta
get kCrateBridgeWrapperSignalRustSignalGeneratePqcPrekeysConstMeta =>
const TaskConstMeta(
debugName: "rust_signal_generate_pqc_prekeys",
argNames: [],
);
@override
Future<void> crateBridgeWrapperSignalRustSignalProcessPrekeyBundle({
required String name,
required int deviceId,
required FrbPreKeyBundle bundle,
}) {
return handler.executeNormal(
NormalTask(
callFfi: (port_) {
final serializer = SseSerializer(generalizedFrbRustBinding);
sse_encode_String(name, serializer);
sse_encode_u_32(deviceId, serializer);
sse_encode_box_autoadd_frb_pre_key_bundle(bundle, serializer);
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 36,
port: port_,
);
},
codec: SseCodec(
decodeSuccessData: sse_decode_unit,
decodeErrorData: sse_decode_AnyhowException,
),
constMeta:
kCrateBridgeWrapperSignalRustSignalProcessPrekeyBundleConstMeta,
argValues: [name, deviceId, bundle],
apiImpl: this,
),
);
}
TaskConstMeta
get kCrateBridgeWrapperSignalRustSignalProcessPrekeyBundleConstMeta =>
const TaskConstMeta(
debugName: "rust_signal_process_prekey_bundle",
argNames: ["name", "deviceId", "bundle"],
);
@override
Future<List<Uint8List>> crateBridgeWrapperRustUtilsGenerateShares({
required List<int> secret,
@ -1667,7 +1869,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 32,
funcId: 37,
port: port_,
);
},
@ -1702,7 +1904,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 33,
funcId: 38,
port: port_,
);
},
@ -1738,7 +1940,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 34,
funcId: 39,
port: port_,
);
},
@ -1775,7 +1977,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 35,
funcId: 40,
port: port_,
);
},
@ -1813,7 +2015,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 36,
funcId: 41,
port: port_,
);
},
@ -1851,7 +2053,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 37,
funcId: 42,
port: port_,
);
},
@ -1889,7 +2091,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 38,
funcId: 43,
port: port_,
);
},
@ -1928,7 +2130,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 39,
funcId: 44,
port: port_,
);
},
@ -1967,7 +2169,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 40,
funcId: 45,
port: port_,
);
},
@ -2012,7 +2214,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 41,
funcId: 46,
port: port_,
);
},
@ -2064,7 +2266,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 42,
funcId: 47,
port: port_,
);
},
@ -2105,7 +2307,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 43,
funcId: 48,
port: port_,
);
},
@ -2143,7 +2345,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 44,
funcId: 49,
port: port_,
);
},
@ -2181,7 +2383,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 45,
funcId: 50,
port: port_,
);
},
@ -2219,7 +2421,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 46,
funcId: 51,
port: port_,
);
},
@ -2257,7 +2459,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 47,
funcId: 52,
port: port_,
);
},
@ -2299,7 +2501,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 48,
funcId: 53,
port: port_,
);
},
@ -2339,7 +2541,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
pdeCallFfi(
generalizedFrbRustBinding,
serializer,
funcId: 49,
funcId: 54,
port: port_,
);
},
@ -2978,6 +3180,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_backup_password_keys(raw);
}
@protected
FrbPreKeyBundle dco_decode_box_autoadd_frb_pre_key_bundle(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_frb_pre_key_bundle(raw);
}
@protected
PlatformInt64 dco_decode_box_autoadd_i_64(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@ -2996,6 +3204,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_other_promotion(raw);
}
@protected
int dco_decode_box_autoadd_u_32(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return raw as int;
}
@protected
UserDiscoveryStoreFlutter dco_decode_box_autoadd_user_discovery_store_flutter(
dynamic raw,
@ -3021,6 +3235,42 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return FlutterUserDiscovery();
}
@protected
FrbPqcPreKey dco_decode_frb_pqc_pre_key(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 5)
throw Exception('unexpected arr length: expect 5 but see ${arr.length}');
return FrbPqcPreKey(
eccPreKeyId: dco_decode_u_32(arr[0]),
eccPreKey: dco_decode_list_prim_u_8_strict(arr[1]),
kyberPreKeyId: dco_decode_u_32(arr[2]),
kyberPreKey: dco_decode_list_prim_u_8_strict(arr[3]),
kyberPreKeySignature: dco_decode_list_prim_u_8_strict(arr[4]),
);
}
@protected
FrbPreKeyBundle dco_decode_frb_pre_key_bundle(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 11)
throw Exception('unexpected arr length: expect 11 but see ${arr.length}');
return FrbPreKeyBundle(
registrationId: dco_decode_u_32(arr[0]),
deviceId: dco_decode_u_32(arr[1]),
preKeyId: dco_decode_opt_box_autoadd_u_32(arr[2]),
preKeyPublic: dco_decode_opt_list_prim_u_8_strict(arr[3]),
signedPreKeyId: dco_decode_u_32(arr[4]),
signedPreKeyPublic: dco_decode_list_prim_u_8_strict(arr[5]),
signedPreKeySignature: dco_decode_list_prim_u_8_strict(arr[6]),
kyberPreKeyId: dco_decode_u_32(arr[7]),
kyberPreKeyPublic: dco_decode_list_prim_u_8_strict(arr[8]),
kyberPreKeySignature: dco_decode_list_prim_u_8_strict(arr[9]),
identityKey: dco_decode_list_prim_u_8_strict(arr[10]),
);
}
@protected
PlatformInt64 dco_decode_i_64(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@ -3045,6 +3295,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dcoDecodeI64(raw);
}
@protected
List<FrbPqcPreKey> dco_decode_list_frb_pqc_pre_key(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return (raw as List<dynamic>).map(dco_decode_frb_pqc_pre_key).toList();
}
@protected
List<Uint8List> dco_decode_list_list_prim_u_8_strict(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@ -3096,6 +3352,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw == null ? null : dco_decode_box_autoadd_i_64(raw);
}
@protected
int? dco_decode_opt_box_autoadd_u_32(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return raw == null ? null : dco_decode_box_autoadd_u_32(raw);
}
@protected
List<Uint8List>? dco_decode_opt_list_list_prim_u_8_strict(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@ -3200,6 +3462,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return RustKeyManager();
}
@protected
RustSignal dco_decode_rust_signal(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 0)
throw Exception('unexpected arr length: expect 0 but see ${arr.length}');
return RustSignal();
}
@protected
RustUtils dco_decode_rust_utils(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@ -3347,6 +3618,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_backup_password_keys(deserializer));
}
@protected
FrbPreKeyBundle sse_decode_box_autoadd_frb_pre_key_bundle(
SseDeserializer deserializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_frb_pre_key_bundle(deserializer));
}
@protected
PlatformInt64 sse_decode_box_autoadd_i_64(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -3367,6 +3646,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_other_promotion(deserializer));
}
@protected
int sse_decode_box_autoadd_u_32(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_u_32(deserializer));
}
@protected
UserDiscoveryStoreFlutter sse_decode_box_autoadd_user_discovery_store_flutter(
SseDeserializer deserializer,
@ -3391,6 +3676,58 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return FlutterUserDiscovery();
}
@protected
FrbPqcPreKey sse_decode_frb_pqc_pre_key(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_eccPreKeyId = sse_decode_u_32(deserializer);
var var_eccPreKey = sse_decode_list_prim_u_8_strict(deserializer);
var var_kyberPreKeyId = sse_decode_u_32(deserializer);
var var_kyberPreKey = sse_decode_list_prim_u_8_strict(deserializer);
var var_kyberPreKeySignature = sse_decode_list_prim_u_8_strict(
deserializer,
);
return FrbPqcPreKey(
eccPreKeyId: var_eccPreKeyId,
eccPreKey: var_eccPreKey,
kyberPreKeyId: var_kyberPreKeyId,
kyberPreKey: var_kyberPreKey,
kyberPreKeySignature: var_kyberPreKeySignature,
);
}
@protected
FrbPreKeyBundle sse_decode_frb_pre_key_bundle(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_registrationId = sse_decode_u_32(deserializer);
var var_deviceId = sse_decode_u_32(deserializer);
var var_preKeyId = sse_decode_opt_box_autoadd_u_32(deserializer);
var var_preKeyPublic = sse_decode_opt_list_prim_u_8_strict(deserializer);
var var_signedPreKeyId = sse_decode_u_32(deserializer);
var var_signedPreKeyPublic = sse_decode_list_prim_u_8_strict(deserializer);
var var_signedPreKeySignature = sse_decode_list_prim_u_8_strict(
deserializer,
);
var var_kyberPreKeyId = sse_decode_u_32(deserializer);
var var_kyberPreKeyPublic = sse_decode_list_prim_u_8_strict(deserializer);
var var_kyberPreKeySignature = sse_decode_list_prim_u_8_strict(
deserializer,
);
var var_identityKey = sse_decode_list_prim_u_8_strict(deserializer);
return FrbPreKeyBundle(
registrationId: var_registrationId,
deviceId: var_deviceId,
preKeyId: var_preKeyId,
preKeyPublic: var_preKeyPublic,
signedPreKeyId: var_signedPreKeyId,
signedPreKeyPublic: var_signedPreKeyPublic,
signedPreKeySignature: var_signedPreKeySignature,
kyberPreKeyId: var_kyberPreKeyId,
kyberPreKeyPublic: var_kyberPreKeyPublic,
kyberPreKeySignature: var_kyberPreKeySignature,
identityKey: var_identityKey,
);
}
@protected
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -3411,6 +3748,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return deserializer.buffer.getPlatformInt64();
}
@protected
List<FrbPqcPreKey> sse_decode_list_frb_pqc_pre_key(
SseDeserializer deserializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
var len_ = sse_decode_i_32(deserializer);
var ans_ = <FrbPqcPreKey>[];
for (var idx_ = 0; idx_ < len_; ++idx_) {
ans_.add(sse_decode_frb_pqc_pre_key(deserializer));
}
return ans_;
}
@protected
List<Uint8List> sse_decode_list_list_prim_u_8_strict(
SseDeserializer deserializer,
@ -3503,6 +3854,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
int? sse_decode_opt_box_autoadd_u_32(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
if (sse_decode_bool(deserializer)) {
return (sse_decode_box_autoadd_u_32(deserializer));
} else {
return null;
}
}
@protected
List<Uint8List>? sse_decode_opt_list_list_prim_u_8_strict(
SseDeserializer deserializer,
@ -3613,6 +3975,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return RustKeyManager();
}
@protected
RustSignal sse_decode_rust_signal(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return RustSignal();
}
@protected
RustUtils sse_decode_rust_utils(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -3946,6 +4314,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_backup_password_keys(self, serializer);
}
@protected
void sse_encode_box_autoadd_frb_pre_key_bundle(
FrbPreKeyBundle self,
SseSerializer serializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_frb_pre_key_bundle(self, serializer);
}
@protected
void sse_encode_box_autoadd_i_64(
PlatformInt64 self,
@ -3973,6 +4350,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_other_promotion(self, serializer);
}
@protected
void sse_encode_box_autoadd_u_32(int self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_u_32(self, serializer);
}
@protected
void sse_encode_box_autoadd_user_discovery_store_flutter(
UserDiscoveryStoreFlutter self,
@ -3999,6 +4382,35 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
// Codec=Sse (Serialization based), see doc to use other codecs
}
@protected
void sse_encode_frb_pqc_pre_key(FrbPqcPreKey self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_u_32(self.eccPreKeyId, serializer);
sse_encode_list_prim_u_8_strict(self.eccPreKey, serializer);
sse_encode_u_32(self.kyberPreKeyId, serializer);
sse_encode_list_prim_u_8_strict(self.kyberPreKey, serializer);
sse_encode_list_prim_u_8_strict(self.kyberPreKeySignature, serializer);
}
@protected
void sse_encode_frb_pre_key_bundle(
FrbPreKeyBundle self,
SseSerializer serializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_u_32(self.registrationId, serializer);
sse_encode_u_32(self.deviceId, serializer);
sse_encode_opt_box_autoadd_u_32(self.preKeyId, serializer);
sse_encode_opt_list_prim_u_8_strict(self.preKeyPublic, serializer);
sse_encode_u_32(self.signedPreKeyId, serializer);
sse_encode_list_prim_u_8_strict(self.signedPreKeyPublic, serializer);
sse_encode_list_prim_u_8_strict(self.signedPreKeySignature, serializer);
sse_encode_u_32(self.kyberPreKeyId, serializer);
sse_encode_list_prim_u_8_strict(self.kyberPreKeyPublic, serializer);
sse_encode_list_prim_u_8_strict(self.kyberPreKeySignature, serializer);
sse_encode_list_prim_u_8_strict(self.identityKey, serializer);
}
@protected
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@ -4018,6 +4430,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
serializer.buffer.putPlatformInt64(self);
}
@protected
void sse_encode_list_frb_pqc_pre_key(
List<FrbPqcPreKey> self,
SseSerializer serializer,
) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_i_32(self.length, serializer);
for (final item in self) {
sse_encode_frb_pqc_pre_key(item, serializer);
}
}
@protected
void sse_encode_list_list_prim_u_8_strict(
List<Uint8List> self,
@ -4112,6 +4536,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_opt_box_autoadd_u_32(int? self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_bool(self != null, serializer);
if (self != null) {
sse_encode_box_autoadd_u_32(self, serializer);
}
}
@protected
void sse_encode_opt_list_list_prim_u_8_strict(
List<Uint8List>? self,
@ -4222,6 +4656,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
// Codec=Sse (Serialization based), see doc to use other codecs
}
@protected
void sse_encode_rust_signal(RustSignal self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
}
@protected
void sse_encode_rust_utils(RustUtils self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs

View file

@ -9,6 +9,7 @@ import 'bridge/callbacks/user_discovery.dart';
import 'bridge/wrapper.dart';
import 'bridge/wrapper/backup.dart';
import 'bridge/wrapper/key_manager.dart';
import 'bridge/wrapper/signal.dart';
import 'bridge/wrapper/user_discovery.dart';
import 'dart:async';
import 'dart:convert';
@ -17,6 +18,7 @@ import 'frb_generated.dart';
import 'keys/backup_password_keys.dart';
import 'lib.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_io.dart';
import 'signal/engine.dart';
abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
RustLibApiImplPlatform({
@ -130,6 +132,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
BackupPasswordKeys dco_decode_box_autoadd_backup_password_keys(dynamic raw);
@protected
FrbPreKeyBundle dco_decode_box_autoadd_frb_pre_key_bundle(dynamic raw);
@protected
PlatformInt64 dco_decode_box_autoadd_i_64(dynamic raw);
@ -139,6 +144,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
OtherPromotion dco_decode_box_autoadd_other_promotion(dynamic raw);
@protected
int dco_decode_box_autoadd_u_32(dynamic raw);
@protected
UserDiscoveryStoreFlutter dco_decode_box_autoadd_user_discovery_store_flutter(
dynamic raw,
@ -152,6 +160,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
FlutterUserDiscovery dco_decode_flutter_user_discovery(dynamic raw);
@protected
FrbPqcPreKey dco_decode_frb_pqc_pre_key(dynamic raw);
@protected
FrbPreKeyBundle dco_decode_frb_pre_key_bundle(dynamic raw);
@protected
PlatformInt64 dco_decode_i_64(dynamic raw);
@ -161,6 +175,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64 dco_decode_isize(dynamic raw);
@protected
List<FrbPqcPreKey> dco_decode_list_frb_pqc_pre_key(dynamic raw);
@protected
List<Uint8List> dco_decode_list_list_prim_u_8_strict(dynamic raw);
@ -186,6 +203,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw);
@protected
int? dco_decode_opt_box_autoadd_u_32(dynamic raw);
@protected
List<Uint8List>? dco_decode_opt_list_list_prim_u_8_strict(dynamic raw);
@ -220,6 +240,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustKeyManager dco_decode_rust_key_manager(dynamic raw);
@protected
RustSignal dco_decode_rust_signal(dynamic raw);
@protected
RustUtils dco_decode_rust_utils(dynamic raw);
@ -288,6 +311,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseDeserializer deserializer,
);
@protected
FrbPreKeyBundle sse_decode_box_autoadd_frb_pre_key_bundle(
SseDeserializer deserializer,
);
@protected
PlatformInt64 sse_decode_box_autoadd_i_64(SseDeserializer deserializer);
@ -299,6 +327,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseDeserializer deserializer,
);
@protected
int sse_decode_box_autoadd_u_32(SseDeserializer deserializer);
@protected
UserDiscoveryStoreFlutter sse_decode_box_autoadd_user_discovery_store_flutter(
SseDeserializer deserializer,
@ -314,6 +345,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseDeserializer deserializer,
);
@protected
FrbPqcPreKey sse_decode_frb_pqc_pre_key(SseDeserializer deserializer);
@protected
FrbPreKeyBundle sse_decode_frb_pre_key_bundle(SseDeserializer deserializer);
@protected
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
@ -323,6 +360,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64 sse_decode_isize(SseDeserializer deserializer);
@protected
List<FrbPqcPreKey> sse_decode_list_frb_pqc_pre_key(
SseDeserializer deserializer,
);
@protected
List<Uint8List> sse_decode_list_list_prim_u_8_strict(
SseDeserializer deserializer,
@ -356,6 +398,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer);
@protected
int? sse_decode_opt_box_autoadd_u_32(SseDeserializer deserializer);
@protected
List<Uint8List>? sse_decode_opt_list_list_prim_u_8_strict(
SseDeserializer deserializer,
@ -400,6 +445,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustKeyManager sse_decode_rust_key_manager(SseDeserializer deserializer);
@protected
RustSignal sse_decode_rust_signal(SseDeserializer deserializer);
@protected
RustUtils sse_decode_rust_utils(SseDeserializer deserializer);
@ -561,6 +609,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_box_autoadd_frb_pre_key_bundle(
FrbPreKeyBundle self,
SseSerializer serializer,
);
@protected
void sse_encode_box_autoadd_i_64(
PlatformInt64 self,
@ -579,6 +633,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_box_autoadd_u_32(int self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_user_discovery_store_flutter(
UserDiscoveryStoreFlutter self,
@ -597,6 +654,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_frb_pqc_pre_key(FrbPqcPreKey self, SseSerializer serializer);
@protected
void sse_encode_frb_pre_key_bundle(
FrbPreKeyBundle self,
SseSerializer serializer,
);
@protected
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
@ -606,6 +672,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_isize(PlatformInt64 self, SseSerializer serializer);
@protected
void sse_encode_list_frb_pqc_pre_key(
List<FrbPqcPreKey> self,
SseSerializer serializer,
);
@protected
void sse_encode_list_list_prim_u_8_strict(
List<Uint8List> self,
@ -648,6 +720,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_opt_box_autoadd_u_32(int? self, SseSerializer serializer);
@protected
void sse_encode_opt_list_list_prim_u_8_strict(
List<Uint8List>? self,
@ -708,6 +783,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_rust_signal(RustSignal self, SseSerializer serializer);
@protected
void sse_encode_rust_utils(RustUtils self, SseSerializer serializer);

View file

@ -12,6 +12,7 @@ import 'bridge/callbacks/user_discovery.dart';
import 'bridge/wrapper.dart';
import 'bridge/wrapper/backup.dart';
import 'bridge/wrapper/key_manager.dart';
import 'bridge/wrapper/signal.dart';
import 'bridge/wrapper/user_discovery.dart';
import 'dart:async';
import 'dart:convert';
@ -19,6 +20,7 @@ import 'frb_generated.dart';
import 'keys/backup_password_keys.dart';
import 'lib.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated_web.dart';
import 'signal/engine.dart';
abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
RustLibApiImplPlatform({
@ -132,6 +134,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
BackupPasswordKeys dco_decode_box_autoadd_backup_password_keys(dynamic raw);
@protected
FrbPreKeyBundle dco_decode_box_autoadd_frb_pre_key_bundle(dynamic raw);
@protected
PlatformInt64 dco_decode_box_autoadd_i_64(dynamic raw);
@ -141,6 +146,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
OtherPromotion dco_decode_box_autoadd_other_promotion(dynamic raw);
@protected
int dco_decode_box_autoadd_u_32(dynamic raw);
@protected
UserDiscoveryStoreFlutter dco_decode_box_autoadd_user_discovery_store_flutter(
dynamic raw,
@ -154,6 +162,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
FlutterUserDiscovery dco_decode_flutter_user_discovery(dynamic raw);
@protected
FrbPqcPreKey dco_decode_frb_pqc_pre_key(dynamic raw);
@protected
FrbPreKeyBundle dco_decode_frb_pre_key_bundle(dynamic raw);
@protected
PlatformInt64 dco_decode_i_64(dynamic raw);
@ -163,6 +177,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64 dco_decode_isize(dynamic raw);
@protected
List<FrbPqcPreKey> dco_decode_list_frb_pqc_pre_key(dynamic raw);
@protected
List<Uint8List> dco_decode_list_list_prim_u_8_strict(dynamic raw);
@ -188,6 +205,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw);
@protected
int? dco_decode_opt_box_autoadd_u_32(dynamic raw);
@protected
List<Uint8List>? dco_decode_opt_list_list_prim_u_8_strict(dynamic raw);
@ -222,6 +242,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustKeyManager dco_decode_rust_key_manager(dynamic raw);
@protected
RustSignal dco_decode_rust_signal(dynamic raw);
@protected
RustUtils dco_decode_rust_utils(dynamic raw);
@ -290,6 +313,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseDeserializer deserializer,
);
@protected
FrbPreKeyBundle sse_decode_box_autoadd_frb_pre_key_bundle(
SseDeserializer deserializer,
);
@protected
PlatformInt64 sse_decode_box_autoadd_i_64(SseDeserializer deserializer);
@ -301,6 +329,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseDeserializer deserializer,
);
@protected
int sse_decode_box_autoadd_u_32(SseDeserializer deserializer);
@protected
UserDiscoveryStoreFlutter sse_decode_box_autoadd_user_discovery_store_flutter(
SseDeserializer deserializer,
@ -316,6 +347,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseDeserializer deserializer,
);
@protected
FrbPqcPreKey sse_decode_frb_pqc_pre_key(SseDeserializer deserializer);
@protected
FrbPreKeyBundle sse_decode_frb_pre_key_bundle(SseDeserializer deserializer);
@protected
PlatformInt64 sse_decode_i_64(SseDeserializer deserializer);
@ -325,6 +362,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64 sse_decode_isize(SseDeserializer deserializer);
@protected
List<FrbPqcPreKey> sse_decode_list_frb_pqc_pre_key(
SseDeserializer deserializer,
);
@protected
List<Uint8List> sse_decode_list_list_prim_u_8_strict(
SseDeserializer deserializer,
@ -358,6 +400,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer);
@protected
int? sse_decode_opt_box_autoadd_u_32(SseDeserializer deserializer);
@protected
List<Uint8List>? sse_decode_opt_list_list_prim_u_8_strict(
SseDeserializer deserializer,
@ -402,6 +447,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
RustKeyManager sse_decode_rust_key_manager(SseDeserializer deserializer);
@protected
RustSignal sse_decode_rust_signal(SseDeserializer deserializer);
@protected
RustUtils sse_decode_rust_utils(SseDeserializer deserializer);
@ -563,6 +611,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_box_autoadd_frb_pre_key_bundle(
FrbPreKeyBundle self,
SseSerializer serializer,
);
@protected
void sse_encode_box_autoadd_i_64(
PlatformInt64 self,
@ -581,6 +635,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_box_autoadd_u_32(int self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_user_discovery_store_flutter(
UserDiscoveryStoreFlutter self,
@ -599,6 +656,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_frb_pqc_pre_key(FrbPqcPreKey self, SseSerializer serializer);
@protected
void sse_encode_frb_pre_key_bundle(
FrbPreKeyBundle self,
SseSerializer serializer,
);
@protected
void sse_encode_i_64(PlatformInt64 self, SseSerializer serializer);
@ -608,6 +674,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_isize(PlatformInt64 self, SseSerializer serializer);
@protected
void sse_encode_list_frb_pqc_pre_key(
List<FrbPqcPreKey> self,
SseSerializer serializer,
);
@protected
void sse_encode_list_list_prim_u_8_strict(
List<Uint8List> self,
@ -650,6 +722,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_opt_box_autoadd_u_32(int? self, SseSerializer serializer);
@protected
void sse_encode_opt_list_list_prim_u_8_strict(
List<Uint8List>? self,
@ -710,6 +785,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
SseSerializer serializer,
);
@protected
void sse_encode_rust_signal(RustSignal self, SseSerializer serializer);
@protected
void sse_encode_rust_utils(RustUtils self, SseSerializer serializer);

101
lib/core/signal/engine.dart Normal file
View file

@ -0,0 +1,101 @@
// This file is automatically generated, so please do not edit it.
// @generated by `flutter_rust_bridge`@ 2.12.0.
// ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import
import '../frb_generated.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
class FrbPqcPreKey {
final int eccPreKeyId;
final Uint8List eccPreKey;
final int kyberPreKeyId;
final Uint8List kyberPreKey;
final Uint8List kyberPreKeySignature;
const FrbPqcPreKey({
required this.eccPreKeyId,
required this.eccPreKey,
required this.kyberPreKeyId,
required this.kyberPreKey,
required this.kyberPreKeySignature,
});
@override
int get hashCode =>
eccPreKeyId.hashCode ^
eccPreKey.hashCode ^
kyberPreKeyId.hashCode ^
kyberPreKey.hashCode ^
kyberPreKeySignature.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is FrbPqcPreKey &&
runtimeType == other.runtimeType &&
eccPreKeyId == other.eccPreKeyId &&
eccPreKey == other.eccPreKey &&
kyberPreKeyId == other.kyberPreKeyId &&
kyberPreKey == other.kyberPreKey &&
kyberPreKeySignature == other.kyberPreKeySignature;
}
class FrbPreKeyBundle {
final int registrationId;
final int deviceId;
final int? preKeyId;
final Uint8List? preKeyPublic;
final int signedPreKeyId;
final Uint8List signedPreKeyPublic;
final Uint8List signedPreKeySignature;
final int kyberPreKeyId;
final Uint8List kyberPreKeyPublic;
final Uint8List kyberPreKeySignature;
final Uint8List identityKey;
const FrbPreKeyBundle({
required this.registrationId,
required this.deviceId,
this.preKeyId,
this.preKeyPublic,
required this.signedPreKeyId,
required this.signedPreKeyPublic,
required this.signedPreKeySignature,
required this.kyberPreKeyId,
required this.kyberPreKeyPublic,
required this.kyberPreKeySignature,
required this.identityKey,
});
@override
int get hashCode =>
registrationId.hashCode ^
deviceId.hashCode ^
preKeyId.hashCode ^
preKeyPublic.hashCode ^
signedPreKeyId.hashCode ^
signedPreKeyPublic.hashCode ^
signedPreKeySignature.hashCode ^
kyberPreKeyId.hashCode ^
kyberPreKeyPublic.hashCode ^
kyberPreKeySignature.hashCode ^
identityKey.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is FrbPreKeyBundle &&
runtimeType == other.runtimeType &&
registrationId == other.registrationId &&
deviceId == other.deviceId &&
preKeyId == other.preKeyId &&
preKeyPublic == other.preKeyPublic &&
signedPreKeyId == other.signedPreKeyId &&
signedPreKeyPublic == other.signedPreKeyPublic &&
signedPreKeySignature == other.signedPreKeySignature &&
kyberPreKeyId == other.kyberPreKeyId &&
kyberPreKeyPublic == other.kyberPreKeyPublic &&
kyberPreKeySignature == other.kyberPreKeySignature &&
identityKey == other.identityKey;
}

View file

@ -175,13 +175,15 @@ Future<void> postStartupTasks() async {
// 2. Service initializations
unawaited(finishStartedPreprocessing());
unawaited(createPushAvatars());
unawaited(newsService.init().then((_) {
unawaited(
newsService.init().then((_) {
final lastDownload = newsService.lastDownloadedAt;
if (lastDownload == null ||
DateTime.now().difference(lastDownload) >= const Duration(days: 7)) {
newsService.fetchFeed();
}
}));
}),
);
unawaited(UserDiscoveryService.verifyInitializationOnStartup());

File diff suppressed because it is too large Load diff

View file

@ -63,6 +63,7 @@ class SignalSignedPreKeyStore extends SignedPreKeyStore {
.insert(companion, mode: InsertMode.insertOrReplace);
} catch (e) {
Log.error('$e');
rethrow;
}
}

View file

@ -1,5 +1,8 @@
import 'package:drift/drift.dart';
enum SignalVersion { v1, v2 }
@DataClassName('Contact')
class Contacts extends Table {
IntColumn get userId => integer()();
@ -23,6 +26,9 @@ class Contacts extends Table {
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
TextColumn get signalVersion =>
textEnum<SignalVersion>().withDefault(const Constant('v1'))();
// User Discovery
BlobColumn get userDiscoveryVersion => blob().nullable()();
BoolColumn get userDiscoveryExcluded =>

View file

@ -31,7 +31,7 @@ class Groups extends Table {
boolean().withDefault(const Constant(false))();
IntColumn get deleteMessagesAfterMilliseconds => integer().withDefault(
const Constant(defaultDeleteMessagesAfterMilliseconds),
const Constant(1000 * 60 * 60 * 24),
)();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();

View file

@ -87,7 +87,7 @@ class TwonlyDB extends _$TwonlyDB {
TwonlyDB.forTesting(DatabaseConnection super.connection);
@override
int get schemaVersion => 24;
int get schemaVersion => 25;
static QueryExecutor _openConnection() {
final connection = driftDatabase(
@ -294,6 +294,9 @@ class TwonlyDB extends _$TwonlyDB {
await m.createTable(schema.labels);
await m.createTable(schema.contactLabels);
},
from24To25: (m, schema) async {
await m.addColumn(schema.contacts, schema.contacts.signalVersion);
},
)(m, from, to);
},
);

View file

@ -174,6 +174,16 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
requiredDuringInsert: false,
defaultValue: currentDateAndTime,
);
@override
late final GeneratedColumnWithTypeConverter<SignalVersion, String>
signalVersion = GeneratedColumn<String>(
'signal_version',
aliasedName,
false,
type: DriftSqlType.string,
requiredDuringInsert: false,
defaultValue: const Constant('v1'),
).withConverter<SignalVersion>($ContactsTable.$convertersignalVersion);
static const VerificationMeta _userDiscoveryVersionMeta =
const VerificationMeta('userDiscoveryVersion');
@override
@ -337,6 +347,7 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
verified,
accountDeleted,
createdAt,
signalVersion,
userDiscoveryVersion,
userDiscoveryExcluded,
userDiscoveryManualApproved,
@ -626,6 +637,12 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
DriftSqlType.dateTime,
data['${effectivePrefix}created_at'],
)!,
signalVersion: $ContactsTable.$convertersignalVersion.fromSql(
attachedDatabase.typeMapping.read(
DriftSqlType.string,
data['${effectivePrefix}signal_version'],
)!,
),
userDiscoveryVersion: attachedDatabase.typeMapping.read(
DriftSqlType.blob,
data['${effectivePrefix}user_discovery_version'],
@ -681,6 +698,11 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
$ContactsTable createAlias(String alias) {
return $ContactsTable(attachedDatabase, alias);
}
static JsonTypeConverter2<SignalVersion, String, String>
$convertersignalVersion = const EnumNameConverter<SignalVersion>(
SignalVersion.values,
);
}
class Contact extends DataClass implements Insertable<Contact> {
@ -697,6 +719,7 @@ class Contact extends DataClass implements Insertable<Contact> {
final bool verified;
final bool accountDeleted;
final DateTime createdAt;
final SignalVersion signalVersion;
final Uint8List? userDiscoveryVersion;
final bool userDiscoveryExcluded;
final bool? userDiscoveryManualApproved;
@ -723,6 +746,7 @@ class Contact extends DataClass implements Insertable<Contact> {
required this.verified,
required this.accountDeleted,
required this.createdAt,
required this.signalVersion,
this.userDiscoveryVersion,
required this.userDiscoveryExcluded,
this.userDiscoveryManualApproved,
@ -758,6 +782,11 @@ class Contact extends DataClass implements Insertable<Contact> {
map['verified'] = Variable<bool>(verified);
map['account_deleted'] = Variable<bool>(accountDeleted);
map['created_at'] = Variable<DateTime>(createdAt);
{
map['signal_version'] = Variable<String>(
$ContactsTable.$convertersignalVersion.toSql(signalVersion),
);
}
if (!nullToAbsent || userDiscoveryVersion != null) {
map['user_discovery_version'] = Variable<Uint8List>(userDiscoveryVersion);
}
@ -820,6 +849,7 @@ class Contact extends DataClass implements Insertable<Contact> {
verified: Value(verified),
accountDeleted: Value(accountDeleted),
createdAt: Value(createdAt),
signalVersion: Value(signalVersion),
userDiscoveryVersion: userDiscoveryVersion == null && nullToAbsent
? const Value.absent()
: Value(userDiscoveryVersion),
@ -878,6 +908,9 @@ class Contact extends DataClass implements Insertable<Contact> {
verified: serializer.fromJson<bool>(json['verified']),
accountDeleted: serializer.fromJson<bool>(json['accountDeleted']),
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
signalVersion: $ContactsTable.$convertersignalVersion.fromJson(
serializer.fromJson<String>(json['signalVersion']),
),
userDiscoveryVersion: serializer.fromJson<Uint8List?>(
json['userDiscoveryVersion'],
),
@ -931,6 +964,9 @@ class Contact extends DataClass implements Insertable<Contact> {
'verified': serializer.toJson<bool>(verified),
'accountDeleted': serializer.toJson<bool>(accountDeleted),
'createdAt': serializer.toJson<DateTime>(createdAt),
'signalVersion': serializer.toJson<String>(
$ContactsTable.$convertersignalVersion.toJson(signalVersion),
),
'userDiscoveryVersion': serializer.toJson<Uint8List?>(
userDiscoveryVersion,
),
@ -976,6 +1012,7 @@ class Contact extends DataClass implements Insertable<Contact> {
bool? verified,
bool? accountDeleted,
DateTime? createdAt,
SignalVersion? signalVersion,
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
bool? userDiscoveryExcluded,
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
@ -1004,6 +1041,7 @@ class Contact extends DataClass implements Insertable<Contact> {
verified: verified ?? this.verified,
accountDeleted: accountDeleted ?? this.accountDeleted,
createdAt: createdAt ?? this.createdAt,
signalVersion: signalVersion ?? this.signalVersion,
userDiscoveryVersion: userDiscoveryVersion.present
? userDiscoveryVersion.value
: this.userDiscoveryVersion,
@ -1059,6 +1097,9 @@ class Contact extends DataClass implements Insertable<Contact> {
? data.accountDeleted.value
: this.accountDeleted,
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
signalVersion: data.signalVersion.present
? data.signalVersion.value
: this.signalVersion,
userDiscoveryVersion: data.userDiscoveryVersion.present
? data.userDiscoveryVersion.value
: this.userDiscoveryVersion,
@ -1114,6 +1155,7 @@ class Contact extends DataClass implements Insertable<Contact> {
..write('verified: $verified, ')
..write('accountDeleted: $accountDeleted, ')
..write('createdAt: $createdAt, ')
..write('signalVersion: $signalVersion, ')
..write('userDiscoveryVersion: $userDiscoveryVersion, ')
..write('userDiscoveryExcluded: $userDiscoveryExcluded, ')
..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ')
@ -1147,6 +1189,7 @@ class Contact extends DataClass implements Insertable<Contact> {
verified,
accountDeleted,
createdAt,
signalVersion,
$driftBlobEquality.hash(userDiscoveryVersion),
userDiscoveryExcluded,
userDiscoveryManualApproved,
@ -1180,6 +1223,7 @@ class Contact extends DataClass implements Insertable<Contact> {
other.verified == this.verified &&
other.accountDeleted == this.accountDeleted &&
other.createdAt == this.createdAt &&
other.signalVersion == this.signalVersion &&
$driftBlobEquality.equals(
other.userDiscoveryVersion,
this.userDiscoveryVersion,
@ -1219,6 +1263,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
final Value<bool> verified;
final Value<bool> accountDeleted;
final Value<DateTime> createdAt;
final Value<SignalVersion> signalVersion;
final Value<Uint8List?> userDiscoveryVersion;
final Value<bool> userDiscoveryExcluded;
final Value<bool?> userDiscoveryManualApproved;
@ -1245,6 +1290,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
this.verified = const Value.absent(),
this.accountDeleted = const Value.absent(),
this.createdAt = const Value.absent(),
this.signalVersion = const Value.absent(),
this.userDiscoveryVersion = const Value.absent(),
this.userDiscoveryExcluded = const Value.absent(),
this.userDiscoveryManualApproved = const Value.absent(),
@ -1272,6 +1318,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
this.verified = const Value.absent(),
this.accountDeleted = const Value.absent(),
this.createdAt = const Value.absent(),
this.signalVersion = const Value.absent(),
this.userDiscoveryVersion = const Value.absent(),
this.userDiscoveryExcluded = const Value.absent(),
this.userDiscoveryManualApproved = const Value.absent(),
@ -1299,6 +1346,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
Expression<bool>? verified,
Expression<bool>? accountDeleted,
Expression<DateTime>? createdAt,
Expression<String>? signalVersion,
Expression<Uint8List>? userDiscoveryVersion,
Expression<bool>? userDiscoveryExcluded,
Expression<bool>? userDiscoveryManualApproved,
@ -1328,6 +1376,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
if (verified != null) 'verified': verified,
if (accountDeleted != null) 'account_deleted': accountDeleted,
if (createdAt != null) 'created_at': createdAt,
if (signalVersion != null) 'signal_version': signalVersion,
if (userDiscoveryVersion != null)
'user_discovery_version': userDiscoveryVersion,
if (userDiscoveryExcluded != null)
@ -1368,6 +1417,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
Value<bool>? verified,
Value<bool>? accountDeleted,
Value<DateTime>? createdAt,
Value<SignalVersion>? signalVersion,
Value<Uint8List?>? userDiscoveryVersion,
Value<bool>? userDiscoveryExcluded,
Value<bool?>? userDiscoveryManualApproved,
@ -1395,6 +1445,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
verified: verified ?? this.verified,
accountDeleted: accountDeleted ?? this.accountDeleted,
createdAt: createdAt ?? this.createdAt,
signalVersion: signalVersion ?? this.signalVersion,
userDiscoveryVersion: userDiscoveryVersion ?? this.userDiscoveryVersion,
userDiscoveryExcluded:
userDiscoveryExcluded ?? this.userDiscoveryExcluded,
@ -1462,6 +1513,11 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
if (createdAt.present) {
map['created_at'] = Variable<DateTime>(createdAt.value);
}
if (signalVersion.present) {
map['signal_version'] = Variable<String>(
$ContactsTable.$convertersignalVersion.toSql(signalVersion.value),
);
}
if (userDiscoveryVersion.present) {
map['user_discovery_version'] = Variable<Uint8List>(
userDiscoveryVersion.value,
@ -1537,6 +1593,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
..write('verified: $verified, ')
..write('accountDeleted: $accountDeleted, ')
..write('createdAt: $createdAt, ')
..write('signalVersion: $signalVersion, ')
..write('userDiscoveryVersion: $userDiscoveryVersion, ')
..write('userDiscoveryExcluded: $userDiscoveryExcluded, ')
..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ')
@ -1769,7 +1826,7 @@ class $GroupsTable extends Groups with TableInfo<$GroupsTable, Group> {
false,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultValue: const Constant(defaultDeleteMessagesAfterMilliseconds),
defaultValue: const Constant(1000 * 60 * 60 * 24),
);
static const VerificationMeta _createdAtMeta = const VerificationMeta(
'createdAt',
@ -14022,6 +14079,7 @@ typedef $$ContactsTableCreateCompanionBuilder =
Value<bool> verified,
Value<bool> accountDeleted,
Value<DateTime> createdAt,
Value<SignalVersion> signalVersion,
Value<Uint8List?> userDiscoveryVersion,
Value<bool> userDiscoveryExcluded,
Value<bool?> userDiscoveryManualApproved,
@ -14050,6 +14108,7 @@ typedef $$ContactsTableUpdateCompanionBuilder =
Value<bool> verified,
Value<bool> accountDeleted,
Value<DateTime> createdAt,
Value<SignalVersion> signalVersion,
Value<Uint8List?> userDiscoveryVersion,
Value<bool> userDiscoveryExcluded,
Value<bool?> userDiscoveryManualApproved,
@ -14429,6 +14488,12 @@ class $$ContactsTableFilterComposer
builder: (column) => ColumnFilters(column),
);
ColumnWithTypeConverterFilters<SignalVersion, SignalVersion, String>
get signalVersion => $composableBuilder(
column: $table.signalVersion,
builder: (column) => ColumnWithTypeConverterFilters(column),
);
ColumnFilters<Uint8List> get userDiscoveryVersion => $composableBuilder(
column: $table.userDiscoveryVersion,
builder: (column) => ColumnFilters(column),
@ -14874,6 +14939,11 @@ class $$ContactsTableOrderingComposer
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<String> get signalVersion => $composableBuilder(
column: $table.signalVersion,
builder: (column) => ColumnOrderings(column),
);
ColumnOrderings<Uint8List> get userDiscoveryVersion => $composableBuilder(
column: $table.userDiscoveryVersion,
builder: (column) => ColumnOrderings(column),
@ -14995,6 +15065,12 @@ class $$ContactsTableAnnotationComposer
GeneratedColumn<DateTime> get createdAt =>
$composableBuilder(column: $table.createdAt, builder: (column) => column);
GeneratedColumnWithTypeConverter<SignalVersion, String> get signalVersion =>
$composableBuilder(
column: $table.signalVersion,
builder: (column) => column,
);
GeneratedColumn<Uint8List> get userDiscoveryVersion => $composableBuilder(
column: $table.userDiscoveryVersion,
builder: (column) => column,
@ -15425,6 +15501,7 @@ class $$ContactsTableTableManager
Value<bool> verified = const Value.absent(),
Value<bool> accountDeleted = const Value.absent(),
Value<DateTime> createdAt = const Value.absent(),
Value<SignalVersion> signalVersion = const Value.absent(),
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
Value<bool> userDiscoveryExcluded = const Value.absent(),
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
@ -15453,6 +15530,7 @@ class $$ContactsTableTableManager
verified: verified,
accountDeleted: accountDeleted,
createdAt: createdAt,
signalVersion: signalVersion,
userDiscoveryVersion: userDiscoveryVersion,
userDiscoveryExcluded: userDiscoveryExcluded,
userDiscoveryManualApproved: userDiscoveryManualApproved,
@ -15481,6 +15559,7 @@ class $$ContactsTableTableManager
Value<bool> verified = const Value.absent(),
Value<bool> accountDeleted = const Value.absent(),
Value<DateTime> createdAt = const Value.absent(),
Value<SignalVersion> signalVersion = const Value.absent(),
Value<Uint8List?> userDiscoveryVersion = const Value.absent(),
Value<bool> userDiscoveryExcluded = const Value.absent(),
Value<bool?> userDiscoveryManualApproved = const Value.absent(),
@ -15509,6 +15588,7 @@ class $$ContactsTableTableManager
verified: verified,
accountDeleted: accountDeleted,
createdAt: createdAt,
signalVersion: signalVersion,
userDiscoveryVersion: userDiscoveryVersion,
userDiscoveryExcluded: userDiscoveryExcluded,
userDiscoveryManualApproved: userDiscoveryManualApproved,

File diff suppressed because it is too large Load diff

View file

@ -106,6 +106,8 @@ class UserData {
DateTime? signalLastSignedPreKeyUpdated;
DateTime? signalLastPqcPreKeysUploaded;
@JsonKey(defaultValue: false)
bool allowErrorTrackingViaSentry = false;

View file

@ -67,6 +67,10 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) =>
json['signalLastSignedPreKeyUpdated'] == null
? null
: DateTime.parse(json['signalLastSignedPreKeyUpdated'] as String)
..signalLastPqcPreKeysUploaded =
json['signalLastPqcPreKeysUploaded'] == null
? null
: DateTime.parse(json['signalLastPqcPreKeysUploaded'] as String)
..allowErrorTrackingViaSentry =
json['allowErrorTrackingViaSentry'] as bool? ?? false
..screenLockEnabled = json['screenLockEnabled'] as bool? ?? false
@ -158,6 +162,8 @@ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'myBestFriendGroupId': instance.myBestFriendGroupId,
'signalLastSignedPreKeyUpdated': instance.signalLastSignedPreKeyUpdated
?.toIso8601String(),
'signalLastPqcPreKeysUploaded': instance.signalLastPqcPreKeysUploaded
?.toIso8601String(),
'allowErrorTrackingViaSentry': instance.allowErrorTrackingViaSentry,
'screenLockEnabled': instance.screenLockEnabled,
'isCloudBackupEnabled': instance.isCloudBackupEnabled,

View file

@ -2059,6 +2059,250 @@ class ApplicationData_UpdateSignedPreKey extends $pb.GeneratedMessage {
void clearSignedPrekeySignature() => $_clearField(3);
}
class ApplicationData_PqcPreKey extends $pb.GeneratedMessage {
factory ApplicationData_PqcPreKey({
$fixnum.Int64? eccPreKeyId,
$core.List<$core.int>? eccPreKey,
$fixnum.Int64? kyberPreKeyId,
$core.List<$core.int>? kyberPreKey,
$core.List<$core.int>? kyberPreKeySignature,
}) {
final result = create();
if (eccPreKeyId != null) result.eccPreKeyId = eccPreKeyId;
if (eccPreKey != null) result.eccPreKey = eccPreKey;
if (kyberPreKeyId != null) result.kyberPreKeyId = kyberPreKeyId;
if (kyberPreKey != null) result.kyberPreKey = kyberPreKey;
if (kyberPreKeySignature != null)
result.kyberPreKeySignature = kyberPreKeySignature;
return result;
}
ApplicationData_PqcPreKey._();
factory ApplicationData_PqcPreKey.fromBuffer($core.List<$core.int> data,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(data, registry);
factory ApplicationData_PqcPreKey.fromJson($core.String json,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(json, registry);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'ApplicationData.PqcPreKey',
package:
const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'),
createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'eccPreKeyId')
..a<$core.List<$core.int>>(
2, _omitFieldNames ? '' : 'eccPreKey', $pb.PbFieldType.OY)
..aInt64(3, _omitFieldNames ? '' : 'kyberPreKeyId')
..a<$core.List<$core.int>>(
4, _omitFieldNames ? '' : 'kyberPreKey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(
5, _omitFieldNames ? '' : 'kyberPreKeySignature', $pb.PbFieldType.OY)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
ApplicationData_PqcPreKey clone() => deepCopy();
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
ApplicationData_PqcPreKey copyWith(
void Function(ApplicationData_PqcPreKey) updates) =>
super.copyWith((message) => updates(message as ApplicationData_PqcPreKey))
as ApplicationData_PqcPreKey;
@$core.override
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static ApplicationData_PqcPreKey create() => ApplicationData_PqcPreKey._();
@$core.override
ApplicationData_PqcPreKey createEmptyInstance() => create();
@$core.pragma('dart2js:noInline')
static ApplicationData_PqcPreKey getDefault() => _defaultInstance ??=
$pb.GeneratedMessage.$_defaultFor<ApplicationData_PqcPreKey>(create);
static ApplicationData_PqcPreKey? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get eccPreKeyId => $_getI64(0);
@$pb.TagNumber(1)
set eccPreKeyId($fixnum.Int64 value) => $_setInt64(0, value);
@$pb.TagNumber(1)
$core.bool hasEccPreKeyId() => $_has(0);
@$pb.TagNumber(1)
void clearEccPreKeyId() => $_clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get eccPreKey => $_getN(1);
@$pb.TagNumber(2)
set eccPreKey($core.List<$core.int> value) => $_setBytes(1, value);
@$pb.TagNumber(2)
$core.bool hasEccPreKey() => $_has(1);
@$pb.TagNumber(2)
void clearEccPreKey() => $_clearField(2);
@$pb.TagNumber(3)
$fixnum.Int64 get kyberPreKeyId => $_getI64(2);
@$pb.TagNumber(3)
set kyberPreKeyId($fixnum.Int64 value) => $_setInt64(2, value);
@$pb.TagNumber(3)
$core.bool hasKyberPreKeyId() => $_has(2);
@$pb.TagNumber(3)
void clearKyberPreKeyId() => $_clearField(3);
@$pb.TagNumber(4)
$core.List<$core.int> get kyberPreKey => $_getN(3);
@$pb.TagNumber(4)
set kyberPreKey($core.List<$core.int> value) => $_setBytes(3, value);
@$pb.TagNumber(4)
$core.bool hasKyberPreKey() => $_has(3);
@$pb.TagNumber(4)
void clearKyberPreKey() => $_clearField(4);
@$pb.TagNumber(5)
$core.List<$core.int> get kyberPreKeySignature => $_getN(4);
@$pb.TagNumber(5)
set kyberPreKeySignature($core.List<$core.int> value) => $_setBytes(4, value);
@$pb.TagNumber(5)
$core.bool hasKyberPreKeySignature() => $_has(4);
@$pb.TagNumber(5)
void clearKyberPreKeySignature() => $_clearField(5);
}
class ApplicationData_UploadPqcPreKeys extends $pb.GeneratedMessage {
factory ApplicationData_UploadPqcPreKeys({
$fixnum.Int64? eccSignedPrekeyId,
$core.List<$core.int>? eccSignedPrekey,
$core.List<$core.int>? eccSignedPrekeySignature,
$fixnum.Int64? kyberSignedPrekeyId,
$core.List<$core.int>? kyberSignedPrekey,
$core.List<$core.int>? kyberSignedPrekeySignature,
$core.Iterable<ApplicationData_PqcPreKey>? prekeys,
}) {
final result = create();
if (eccSignedPrekeyId != null) result.eccSignedPrekeyId = eccSignedPrekeyId;
if (eccSignedPrekey != null) result.eccSignedPrekey = eccSignedPrekey;
if (eccSignedPrekeySignature != null)
result.eccSignedPrekeySignature = eccSignedPrekeySignature;
if (kyberSignedPrekeyId != null)
result.kyberSignedPrekeyId = kyberSignedPrekeyId;
if (kyberSignedPrekey != null) result.kyberSignedPrekey = kyberSignedPrekey;
if (kyberSignedPrekeySignature != null)
result.kyberSignedPrekeySignature = kyberSignedPrekeySignature;
if (prekeys != null) result.prekeys.addAll(prekeys);
return result;
}
ApplicationData_UploadPqcPreKeys._();
factory ApplicationData_UploadPqcPreKeys.fromBuffer(
$core.List<$core.int> data,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(data, registry);
factory ApplicationData_UploadPqcPreKeys.fromJson($core.String json,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(json, registry);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'ApplicationData.UploadPqcPreKeys',
package:
const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'),
createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'eccSignedPrekeyId')
..a<$core.List<$core.int>>(
2, _omitFieldNames ? '' : 'eccSignedPrekey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(3,
_omitFieldNames ? '' : 'eccSignedPrekeySignature', $pb.PbFieldType.OY)
..aInt64(4, _omitFieldNames ? '' : 'kyberSignedPrekeyId')
..a<$core.List<$core.int>>(
5, _omitFieldNames ? '' : 'kyberSignedPrekey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(6,
_omitFieldNames ? '' : 'kyberSignedPrekeySignature', $pb.PbFieldType.OY)
..pPM<ApplicationData_PqcPreKey>(7, _omitFieldNames ? '' : 'prekeys',
subBuilder: ApplicationData_PqcPreKey.create)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
ApplicationData_UploadPqcPreKeys clone() => deepCopy();
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
ApplicationData_UploadPqcPreKeys copyWith(
void Function(ApplicationData_UploadPqcPreKeys) updates) =>
super.copyWith(
(message) => updates(message as ApplicationData_UploadPqcPreKeys))
as ApplicationData_UploadPqcPreKeys;
@$core.override
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static ApplicationData_UploadPqcPreKeys create() =>
ApplicationData_UploadPqcPreKeys._();
@$core.override
ApplicationData_UploadPqcPreKeys createEmptyInstance() => create();
@$core.pragma('dart2js:noInline')
static ApplicationData_UploadPqcPreKeys getDefault() => _defaultInstance ??=
$pb.GeneratedMessage.$_defaultFor<ApplicationData_UploadPqcPreKeys>(
create);
static ApplicationData_UploadPqcPreKeys? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get eccSignedPrekeyId => $_getI64(0);
@$pb.TagNumber(1)
set eccSignedPrekeyId($fixnum.Int64 value) => $_setInt64(0, value);
@$pb.TagNumber(1)
$core.bool hasEccSignedPrekeyId() => $_has(0);
@$pb.TagNumber(1)
void clearEccSignedPrekeyId() => $_clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get eccSignedPrekey => $_getN(1);
@$pb.TagNumber(2)
set eccSignedPrekey($core.List<$core.int> value) => $_setBytes(1, value);
@$pb.TagNumber(2)
$core.bool hasEccSignedPrekey() => $_has(1);
@$pb.TagNumber(2)
void clearEccSignedPrekey() => $_clearField(2);
@$pb.TagNumber(3)
$core.List<$core.int> get eccSignedPrekeySignature => $_getN(2);
@$pb.TagNumber(3)
set eccSignedPrekeySignature($core.List<$core.int> value) =>
$_setBytes(2, value);
@$pb.TagNumber(3)
$core.bool hasEccSignedPrekeySignature() => $_has(2);
@$pb.TagNumber(3)
void clearEccSignedPrekeySignature() => $_clearField(3);
@$pb.TagNumber(4)
$fixnum.Int64 get kyberSignedPrekeyId => $_getI64(3);
@$pb.TagNumber(4)
set kyberSignedPrekeyId($fixnum.Int64 value) => $_setInt64(3, value);
@$pb.TagNumber(4)
$core.bool hasKyberSignedPrekeyId() => $_has(3);
@$pb.TagNumber(4)
void clearKyberSignedPrekeyId() => $_clearField(4);
@$pb.TagNumber(5)
$core.List<$core.int> get kyberSignedPrekey => $_getN(4);
@$pb.TagNumber(5)
set kyberSignedPrekey($core.List<$core.int> value) => $_setBytes(4, value);
@$pb.TagNumber(5)
$core.bool hasKyberSignedPrekey() => $_has(4);
@$pb.TagNumber(5)
void clearKyberSignedPrekey() => $_clearField(5);
@$pb.TagNumber(6)
$core.List<$core.int> get kyberSignedPrekeySignature => $_getN(5);
@$pb.TagNumber(6)
set kyberSignedPrekeySignature($core.List<$core.int> value) =>
$_setBytes(5, value);
@$pb.TagNumber(6)
$core.bool hasKyberSignedPrekeySignature() => $_has(5);
@$pb.TagNumber(6)
void clearKyberSignedPrekeySignature() => $_clearField(6);
@$pb.TagNumber(7)
$pb.PbList<ApplicationData_PqcPreKey> get prekeys => $_getList(6);
}
class ApplicationData_DownloadDone extends $pb.GeneratedMessage {
factory ApplicationData_DownloadDone({
$core.List<$core.int>? downloadToken,
@ -3085,6 +3329,7 @@ enum ApplicationData_ApplicationData {
getMemoriesUsage,
deleteMemory,
disableMemoriesBackup,
uploadPqcPrekeys,
notSet
}
@ -3117,6 +3362,7 @@ class ApplicationData extends $pb.GeneratedMessage {
ApplicationData_GetMemoriesUsage? getMemoriesUsage,
ApplicationData_DeleteMemory? deleteMemory,
ApplicationData_DisableMemoriesBackup? disableMemoriesBackup,
ApplicationData_UploadPqcPreKeys? uploadPqcPrekeys,
}) {
final result = create();
if (textMessage != null) result.textMessage = textMessage;
@ -3157,6 +3403,7 @@ class ApplicationData extends $pb.GeneratedMessage {
if (deleteMemory != null) result.deleteMemory = deleteMemory;
if (disableMemoriesBackup != null)
result.disableMemoriesBackup = disableMemoriesBackup;
if (uploadPqcPrekeys != null) result.uploadPqcPrekeys = uploadPqcPrekeys;
return result;
}
@ -3198,6 +3445,7 @@ class ApplicationData extends $pb.GeneratedMessage {
37: ApplicationData_ApplicationData.getMemoriesUsage,
38: ApplicationData_ApplicationData.deleteMemory,
39: ApplicationData_ApplicationData.disableMemoriesBackup,
40: ApplicationData_ApplicationData.uploadPqcPrekeys,
0: ApplicationData_ApplicationData.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
@ -3232,7 +3480,8 @@ class ApplicationData extends $pb.GeneratedMessage {
36,
37,
38,
39
39,
40
])
..aOM<ApplicationData_TextMessage>(1, _omitFieldNames ? '' : 'textMessage',
protoName: 'textMessage',
@ -3327,6 +3576,9 @@ class ApplicationData extends $pb.GeneratedMessage {
..aOM<ApplicationData_DisableMemoriesBackup>(
39, _omitFieldNames ? '' : 'disableMemoriesBackup',
subBuilder: ApplicationData_DisableMemoriesBackup.create)
..aOM<ApplicationData_UploadPqcPreKeys>(
40, _omitFieldNames ? '' : 'uploadPqcPrekeys',
subBuilder: ApplicationData_UploadPqcPreKeys.create)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@ -3375,6 +3627,7 @@ class ApplicationData extends $pb.GeneratedMessage {
@$pb.TagNumber(37)
@$pb.TagNumber(38)
@$pb.TagNumber(39)
@$pb.TagNumber(40)
ApplicationData_ApplicationData whichApplicationData() =>
_ApplicationData_ApplicationDataByTag[$_whichOneof(0)]!;
@$pb.TagNumber(1)
@ -3404,6 +3657,7 @@ class ApplicationData extends $pb.GeneratedMessage {
@$pb.TagNumber(37)
@$pb.TagNumber(38)
@$pb.TagNumber(39)
@$pb.TagNumber(40)
void clearApplicationData() => $_clearField($_whichOneof(0));
@$pb.TagNumber(1)
@ -3737,6 +3991,18 @@ class ApplicationData extends $pb.GeneratedMessage {
@$pb.TagNumber(39)
ApplicationData_DisableMemoriesBackup ensureDisableMemoriesBackup() =>
$_ensure(26);
@$pb.TagNumber(40)
ApplicationData_UploadPqcPreKeys get uploadPqcPrekeys => $_getN(27);
@$pb.TagNumber(40)
set uploadPqcPrekeys(ApplicationData_UploadPqcPreKeys value) =>
$_setField(40, value);
@$pb.TagNumber(40)
$core.bool hasUploadPqcPrekeys() => $_has(27);
@$pb.TagNumber(40)
void clearUploadPqcPrekeys() => $_clearField(40);
@$pb.TagNumber(40)
ApplicationData_UploadPqcPreKeys ensureUploadPqcPrekeys() => $_ensure(27);
}
class Response_PreKey extends $pb.GeneratedMessage {
@ -3857,16 +4123,68 @@ class Response_Prekeys extends $pb.GeneratedMessage {
$pb.PbList<Response_PreKey> get prekeys => $_getList(0);
}
enum Response_Ok_Ok { none, prekeys, notSet }
class Response_PqcPrekeys extends $pb.GeneratedMessage {
factory Response_PqcPrekeys({
$core.Iterable<ApplicationData_PqcPreKey>? prekeys,
}) {
final result = create();
if (prekeys != null) result.prekeys.addAll(prekeys);
return result;
}
Response_PqcPrekeys._();
factory Response_PqcPrekeys.fromBuffer($core.List<$core.int> data,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(data, registry);
factory Response_PqcPrekeys.fromJson($core.String json,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(json, registry);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'Response.PqcPrekeys',
package:
const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'),
createEmptyInstance: create)
..pPM<ApplicationData_PqcPreKey>(1, _omitFieldNames ? '' : 'prekeys',
subBuilder: ApplicationData_PqcPreKey.create)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_PqcPrekeys clone() => deepCopy();
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_PqcPrekeys copyWith(void Function(Response_PqcPrekeys) updates) =>
super.copyWith((message) => updates(message as Response_PqcPrekeys))
as Response_PqcPrekeys;
@$core.override
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Response_PqcPrekeys create() => Response_PqcPrekeys._();
@$core.override
Response_PqcPrekeys createEmptyInstance() => create();
@$core.pragma('dart2js:noInline')
static Response_PqcPrekeys getDefault() => _defaultInstance ??=
$pb.GeneratedMessage.$_defaultFor<Response_PqcPrekeys>(create);
static Response_PqcPrekeys? _defaultInstance;
@$pb.TagNumber(1)
$pb.PbList<ApplicationData_PqcPreKey> get prekeys => $_getList(0);
}
enum Response_Ok_Ok { none, prekeys, prekeysPqc, notSet }
class Response_Ok extends $pb.GeneratedMessage {
factory Response_Ok({
$core.bool? none,
Response_Prekeys? prekeys,
Response_PqcPrekeys? prekeysPqc,
}) {
final result = create();
if (none != null) result.none = none;
if (prekeys != null) result.prekeys = prekeys;
if (prekeysPqc != null) result.prekeysPqc = prekeysPqc;
return result;
}
@ -3882,6 +4200,7 @@ class Response_Ok extends $pb.GeneratedMessage {
static const $core.Map<$core.int, Response_Ok_Ok> _Response_Ok_OkByTag = {
1: Response_Ok_Ok.none,
2: Response_Ok_Ok.prekeys,
3: Response_Ok_Ok.prekeysPqc,
0: Response_Ok_Ok.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
@ -3889,10 +4208,12 @@ class Response_Ok extends $pb.GeneratedMessage {
package:
const $pb.PackageName(_omitMessageNames ? '' : 'client_to_server'),
createEmptyInstance: create)
..oo(0, [1, 2])
..oo(0, [1, 2, 3])
..aOB(1, _omitFieldNames ? '' : 'None', protoName: 'None')
..aOM<Response_Prekeys>(2, _omitFieldNames ? '' : 'prekeys',
subBuilder: Response_Prekeys.create)
..aOM<Response_PqcPrekeys>(3, _omitFieldNames ? '' : 'prekeysPqc',
subBuilder: Response_PqcPrekeys.create)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@ -3916,9 +4237,11 @@ class Response_Ok extends $pb.GeneratedMessage {
@$pb.TagNumber(1)
@$pb.TagNumber(2)
@$pb.TagNumber(3)
Response_Ok_Ok whichOk() => _Response_Ok_OkByTag[$_whichOneof(0)]!;
@$pb.TagNumber(1)
@$pb.TagNumber(2)
@$pb.TagNumber(3)
void clearOk() => $_clearField($_whichOneof(0));
@$pb.TagNumber(1)
@ -3940,6 +4263,17 @@ class Response_Ok extends $pb.GeneratedMessage {
void clearPrekeys() => $_clearField(2);
@$pb.TagNumber(2)
Response_Prekeys ensurePrekeys() => $_ensure(1);
@$pb.TagNumber(3)
Response_PqcPrekeys get prekeysPqc => $_getN(2);
@$pb.TagNumber(3)
set prekeysPqc(Response_PqcPrekeys value) => $_setField(3, value);
@$pb.TagNumber(3)
$core.bool hasPrekeysPqc() => $_has(2);
@$pb.TagNumber(3)
void clearPrekeysPqc() => $_clearField(3);
@$pb.TagNumber(3)
Response_PqcPrekeys ensurePrekeysPqc() => $_ensure(2);
}
enum Response_Response { ok, error, notSet }

View file

@ -724,6 +724,15 @@ const ApplicationData$json = {
'9': 0,
'10': 'disableMemoriesBackup'
},
{
'1': 'upload_pqc_prekeys',
'3': 40,
'4': 1,
'5': 11,
'6': '.client_to_server.ApplicationData.UploadPqcPreKeys',
'9': 0,
'10': 'uploadPqcPrekeys'
},
],
'3': [
ApplicationData_TextMessage$json,
@ -737,6 +746,8 @@ const ApplicationData$json = {
ApplicationData_GetPrekeysByUserId$json,
ApplicationData_GetSignedPreKeyByUserId$json,
ApplicationData_UpdateSignedPreKey$json,
ApplicationData_PqcPreKey$json,
ApplicationData_UploadPqcPreKeys$json,
ApplicationData_DownloadDone$json,
ApplicationData_ReportUser$json,
ApplicationData_IPAPurchase$json,
@ -868,6 +879,81 @@ const ApplicationData_UpdateSignedPreKey$json = {
],
};
@$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData_PqcPreKey$json = {
'1': 'PqcPreKey',
'2': [
{'1': 'ecc_pre_key_id', '3': 1, '4': 1, '5': 3, '10': 'eccPreKeyId'},
{'1': 'ecc_pre_key', '3': 2, '4': 1, '5': 12, '10': 'eccPreKey'},
{'1': 'kyber_pre_key_id', '3': 3, '4': 1, '5': 3, '10': 'kyberPreKeyId'},
{'1': 'kyber_pre_key', '3': 4, '4': 1, '5': 12, '10': 'kyberPreKey'},
{
'1': 'kyber_pre_key_signature',
'3': 5,
'4': 1,
'5': 12,
'10': 'kyberPreKeySignature'
},
],
};
@$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData_UploadPqcPreKeys$json = {
'1': 'UploadPqcPreKeys',
'2': [
{
'1': 'ecc_signed_prekey_id',
'3': 1,
'4': 1,
'5': 3,
'10': 'eccSignedPrekeyId'
},
{
'1': 'ecc_signed_prekey',
'3': 2,
'4': 1,
'5': 12,
'10': 'eccSignedPrekey'
},
{
'1': 'ecc_signed_prekey_signature',
'3': 3,
'4': 1,
'5': 12,
'10': 'eccSignedPrekeySignature'
},
{
'1': 'kyber_signed_prekey_id',
'3': 4,
'4': 1,
'5': 3,
'10': 'kyberSignedPrekeyId'
},
{
'1': 'kyber_signed_prekey',
'3': 5,
'4': 1,
'5': 12,
'10': 'kyberSignedPrekey'
},
{
'1': 'kyber_signed_prekey_signature',
'3': 6,
'4': 1,
'5': 12,
'10': 'kyberSignedPrekeySignature'
},
{
'1': 'prekeys',
'3': 7,
'4': 3,
'5': 11,
'6': '.client_to_server.ApplicationData.PqcPreKey',
'10': 'prekeys'
},
],
};
@$core.Deprecated('Use applicationDataDescriptor instead')
const ApplicationData_DownloadDone$json = {
'1': 'DownloadDone',
@ -1073,38 +1159,51 @@ final $typed_data.Uint8List applicationDataDescriptor = $convert.base64Decode(
'CzIuLmNsaWVudF90b19zZXJ2ZXIuQXBwbGljYXRpb25EYXRhLkRlbGV0ZU1lbW9yeUgAUgxkZW'
'xldGVNZW1vcnkScQoXZGlzYWJsZV9tZW1vcmllc19iYWNrdXAYJyABKAsyNy5jbGllbnRfdG9f'
'c2VydmVyLkFwcGxpY2F0aW9uRGF0YS5EaXNhYmxlTWVtb3JpZXNCYWNrdXBIAFIVZGlzYWJsZU'
'1lbW9yaWVzQmFja3VwGmoKC1RleHRNZXNzYWdlEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBIS'
'CgRib2R5GAMgASgMUgRib2R5EiAKCXB1c2hfZGF0YRgEIAEoDEgAUghwdXNoRGF0YYgBAUIMCg'
'pfcHVzaF9kYXRhGi8KEUdldFVzZXJCeVVzZXJuYW1lEhoKCHVzZXJuYW1lGAEgASgJUgh1c2Vy'
'bmFtZRosCg5DaGFuZ2VVc2VybmFtZRIaCgh1c2VybmFtZRgBIAEoCVIIdXNlcm5hbWUaNQoUVX'
'BkYXRlR29vZ2xlRmNtVG9rZW4SHQoKZ29vZ2xlX2ZjbRgBIAEoCVIJZ29vZ2xlRmNtGiYKC0dl'
'dFVzZXJCeUlkEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBoTChFHZXRBdmFpbGFibGVQbGFucx'
'oVChNHZXRDdXJyZW50UGxhbkluZm9zGi8KFFJlbW92ZUFkZGl0aW9uYWxVc2VyEhcKB3VzZXJf'
'aWQYASABKANSBnVzZXJJZBotChJHZXRQcmVrZXlzQnlVc2VySWQSFwoHdXNlcl9pZBgBIAEoA1'
'IGdXNlcklkGjIKF0dldFNpZ25lZFByZUtleUJ5VXNlcklkEhcKB3VzZXJfaWQYASABKANSBnVz'
'ZXJJZBqbAQoSVXBkYXRlU2lnbmVkUHJlS2V5EigKEHNpZ25lZF9wcmVrZXlfaWQYASABKANSDn'
'NpZ25lZFByZWtleUlkEiMKDXNpZ25lZF9wcmVrZXkYAiABKAxSDHNpZ25lZFByZWtleRI2Chdz'
'aWduZWRfcHJla2V5X3NpZ25hdHVyZRgDIAEoDFIVc2lnbmVkUHJla2V5U2lnbmF0dXJlGjUKDE'
'Rvd25sb2FkRG9uZRIlCg5kb3dubG9hZF90b2tlbhgBIAEoDFINZG93bmxvYWRUb2tlbhpOCgpS'
'ZXBvcnRVc2VyEigKEHJlcG9ydGVkX3VzZXJfaWQYASABKANSDnJlcG9ydGVkVXNlcklkEhYKBn'
'JlYXNvbhgCIAEoCVIGcmVhc29uGnEKC0lQQVB1cmNoYXNlEh0KCnByb2R1Y3RfaWQYASABKAlS'
'CXByb2R1Y3RJZBIWCgZzb3VyY2UYAiABKAlSBnNvdXJjZRIrChF2ZXJpZmljYXRpb25fZGF0YR'
'gDIAEoCVIQdmVyaWZpY2F0aW9uRGF0YRoPCg1JUEFGb3JjZUNoZWNrGg8KDURlbGV0ZUFjY291'
'bnQaLAoRQWRkQWRkaXRpb25hbFVzZXISFwoHdXNlcl9pZBgBIAEoA1IGdXNlcklkGjAKDVNldE'
'xvZ2luVG9rZW4SHwoLbG9naW5fdG9rZW4YASABKAxSCmxvZ2luVG9rZW4ajgEKHFJlZ2lzdGVy'
'UGFzc3dvcmRMZXNzUmVjb3ZlcnkSLgoSZW5jcnlwdGVkU2VydmVyS2V5GAEgASgMUhJlbmNyeX'
'B0ZWRTZXJ2ZXJLZXkSKwoOcGluVW5sb2NrVG9rZW4YAiABKAxIAFIOcGluVW5sb2NrVG9rZW6I'
'AQFCEQoPX3BpblVubG9ja1Rva2VuGnAKGFBhc3N3b3JkbGVzc05vdGlmaWNhdGlvbhInCg9ub3'
'RpZmljYXRpb25faWQYASABKAlSDm5vdGlmaWNhdGlvbklkEisKEWVuY3J5cHRlZF9tZXNzYWdl'
'GAIgASgMUhBlbmNyeXB0ZWRNZXNzYWdlGmsKFVJlcXVlc3RNZW1vcmllc1VwbG9hZBISCgRzaX'
'plGAEgASgDUgRzaXplEiMKDW9yaWdpbmFsX2RhdGUYAiABKANSDG9yaWdpbmFsRGF0ZRIZCght'
'ZWRpYV9pZBgDIAEoCVIHbWVkaWFJZBoyChVDb25maXJtTWVtb3JpZXNVcGxvYWQSGQoIbWVkaW'
'FfaWQYASABKAlSB21lZGlhSWQaSAoPR2V0TWVtb3JpZXNMaXN0Eh8KC29mZnNldF9kYXRlGAEg'
'ASgDUgpvZmZzZXREYXRlEhQKBWxpbWl0GAIgASgDUgVsaW1pdBpJCg5HZXRNZW1vcmllc1VybB'
'IZCghtZWRpYV9pZBgBIAEoCVIHbWVkaWFJZBIcCgl0aHVtYm5haWwYAiABKAhSCXRodW1ibmFp'
'bBoSChBHZXRNZW1vcmllc1VzYWdlGikKDERlbGV0ZU1lbW9yeRIZCghtZWRpYV9pZBgBIAEoCV'
'IHbWVkaWFJZBoXChVEaXNhYmxlTWVtb3JpZXNCYWNrdXBCEQoPQXBwbGljYXRpb25EYXRhSgQI'
'CRAKSgQICxAMSgQIDRASSgQIExAU');
'1lbW9yaWVzQmFja3VwEmIKEnVwbG9hZF9wcWNfcHJla2V5cxgoIAEoCzIyLmNsaWVudF90b19z'
'ZXJ2ZXIuQXBwbGljYXRpb25EYXRhLlVwbG9hZFBxY1ByZUtleXNIAFIQdXBsb2FkUHFjUHJla2'
'V5cxpqCgtUZXh0TWVzc2FnZRIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQSEgoEYm9keRgDIAEo'
'DFIEYm9keRIgCglwdXNoX2RhdGEYBCABKAxIAFIIcHVzaERhdGGIAQFCDAoKX3B1c2hfZGF0YR'
'ovChFHZXRVc2VyQnlVc2VybmFtZRIaCgh1c2VybmFtZRgBIAEoCVIIdXNlcm5hbWUaLAoOQ2hh'
'bmdlVXNlcm5hbWUSGgoIdXNlcm5hbWUYASABKAlSCHVzZXJuYW1lGjUKFFVwZGF0ZUdvb2dsZU'
'ZjbVRva2VuEh0KCmdvb2dsZV9mY20YASABKAlSCWdvb2dsZUZjbRomCgtHZXRVc2VyQnlJZBIX'
'Cgd1c2VyX2lkGAEgASgDUgZ1c2VySWQaEwoRR2V0QXZhaWxhYmxlUGxhbnMaFQoTR2V0Q3Vycm'
'VudFBsYW5JbmZvcxovChRSZW1vdmVBZGRpdGlvbmFsVXNlchIXCgd1c2VyX2lkGAEgASgDUgZ1'
'c2VySWQaLQoSR2V0UHJla2V5c0J5VXNlcklkEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBoyCh'
'dHZXRTaWduZWRQcmVLZXlCeVVzZXJJZBIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQamwEKElVw'
'ZGF0ZVNpZ25lZFByZUtleRIoChBzaWduZWRfcHJla2V5X2lkGAEgASgDUg5zaWduZWRQcmVrZX'
'lJZBIjCg1zaWduZWRfcHJla2V5GAIgASgMUgxzaWduZWRQcmVrZXkSNgoXc2lnbmVkX3ByZWtl'
'eV9zaWduYXR1cmUYAyABKAxSFXNpZ25lZFByZWtleVNpZ25hdHVyZRrUAQoJUHFjUHJlS2V5Ei'
'MKDmVjY19wcmVfa2V5X2lkGAEgASgDUgtlY2NQcmVLZXlJZBIeCgtlY2NfcHJlX2tleRgCIAEo'
'DFIJZWNjUHJlS2V5EicKEGt5YmVyX3ByZV9rZXlfaWQYAyABKANSDWt5YmVyUHJlS2V5SWQSIg'
'oNa3liZXJfcHJlX2tleRgEIAEoDFILa3liZXJQcmVLZXkSNQoXa3liZXJfcHJlX2tleV9zaWdu'
'YXR1cmUYBSABKAxSFGt5YmVyUHJlS2V5U2lnbmF0dXJlGp0DChBVcGxvYWRQcWNQcmVLZXlzEi'
'8KFGVjY19zaWduZWRfcHJla2V5X2lkGAEgASgDUhFlY2NTaWduZWRQcmVrZXlJZBIqChFlY2Nf'
'c2lnbmVkX3ByZWtleRgCIAEoDFIPZWNjU2lnbmVkUHJla2V5Ej0KG2VjY19zaWduZWRfcHJla2'
'V5X3NpZ25hdHVyZRgDIAEoDFIYZWNjU2lnbmVkUHJla2V5U2lnbmF0dXJlEjMKFmt5YmVyX3Np'
'Z25lZF9wcmVrZXlfaWQYBCABKANSE2t5YmVyU2lnbmVkUHJla2V5SWQSLgoTa3liZXJfc2lnbm'
'VkX3ByZWtleRgFIAEoDFIRa3liZXJTaWduZWRQcmVrZXkSQQoda3liZXJfc2lnbmVkX3ByZWtl'
'eV9zaWduYXR1cmUYBiABKAxSGmt5YmVyU2lnbmVkUHJla2V5U2lnbmF0dXJlEkUKB3ByZWtleX'
'MYByADKAsyKy5jbGllbnRfdG9fc2VydmVyLkFwcGxpY2F0aW9uRGF0YS5QcWNQcmVLZXlSB3By'
'ZWtleXMaNQoMRG93bmxvYWREb25lEiUKDmRvd25sb2FkX3Rva2VuGAEgASgMUg1kb3dubG9hZF'
'Rva2VuGk4KClJlcG9ydFVzZXISKAoQcmVwb3J0ZWRfdXNlcl9pZBgBIAEoA1IOcmVwb3J0ZWRV'
'c2VySWQSFgoGcmVhc29uGAIgASgJUgZyZWFzb24acQoLSVBBUHVyY2hhc2USHQoKcHJvZHVjdF'
'9pZBgBIAEoCVIJcHJvZHVjdElkEhYKBnNvdXJjZRgCIAEoCVIGc291cmNlEisKEXZlcmlmaWNh'
'dGlvbl9kYXRhGAMgASgJUhB2ZXJpZmljYXRpb25EYXRhGg8KDUlQQUZvcmNlQ2hlY2saDwoNRG'
'VsZXRlQWNjb3VudBosChFBZGRBZGRpdGlvbmFsVXNlchIXCgd1c2VyX2lkGAEgASgDUgZ1c2Vy'
'SWQaMAoNU2V0TG9naW5Ub2tlbhIfCgtsb2dpbl90b2tlbhgBIAEoDFIKbG9naW5Ub2tlbhqOAQ'
'ocUmVnaXN0ZXJQYXNzd29yZExlc3NSZWNvdmVyeRIuChJlbmNyeXB0ZWRTZXJ2ZXJLZXkYASAB'
'KAxSEmVuY3J5cHRlZFNlcnZlcktleRIrCg5waW5VbmxvY2tUb2tlbhgCIAEoDEgAUg5waW5Vbm'
'xvY2tUb2tlbogBAUIRCg9fcGluVW5sb2NrVG9rZW4acAoYUGFzc3dvcmRsZXNzTm90aWZpY2F0'
'aW9uEicKD25vdGlmaWNhdGlvbl9pZBgBIAEoCVIObm90aWZpY2F0aW9uSWQSKwoRZW5jcnlwdG'
'VkX21lc3NhZ2UYAiABKAxSEGVuY3J5cHRlZE1lc3NhZ2UaawoVUmVxdWVzdE1lbW9yaWVzVXBs'
'b2FkEhIKBHNpemUYASABKANSBHNpemUSIwoNb3JpZ2luYWxfZGF0ZRgCIAEoA1IMb3JpZ2luYW'
'xEYXRlEhkKCG1lZGlhX2lkGAMgASgJUgdtZWRpYUlkGjIKFUNvbmZpcm1NZW1vcmllc1VwbG9h'
'ZBIZCghtZWRpYV9pZBgBIAEoCVIHbWVkaWFJZBpICg9HZXRNZW1vcmllc0xpc3QSHwoLb2Zmc2'
'V0X2RhdGUYASABKANSCm9mZnNldERhdGUSFAoFbGltaXQYAiABKANSBWxpbWl0GkkKDkdldE1l'
'bW9yaWVzVXJsEhkKCG1lZGlhX2lkGAEgASgJUgdtZWRpYUlkEhwKCXRodW1ibmFpbBgCIAEoCF'
'IJdGh1bWJuYWlsGhIKEEdldE1lbW9yaWVzVXNhZ2UaKQoMRGVsZXRlTWVtb3J5EhkKCG1lZGlh'
'X2lkGAEgASgJUgdtZWRpYUlkGhcKFURpc2FibGVNZW1vcmllc0JhY2t1cEIRCg9BcHBsaWNhdG'
'lvbkRhdGFKBAgJEApKBAgLEAxKBAgNEBJKBAgTEBQ=');
@$core.Deprecated('Use responseDescriptor instead')
const Response$json = {
@ -1129,7 +1228,12 @@ const Response$json = {
'10': 'error'
},
],
'3': [Response_PreKey$json, Response_Prekeys$json, Response_Ok$json],
'3': [
Response_PreKey$json,
Response_Prekeys$json,
Response_PqcPrekeys$json,
Response_Ok$json
],
'8': [
{'1': 'Response'},
],
@ -1159,6 +1263,21 @@ const Response_Prekeys$json = {
],
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_PqcPrekeys$json = {
'1': 'PqcPrekeys',
'2': [
{
'1': 'prekeys',
'3': 1,
'4': 3,
'5': 11,
'6': '.client_to_server.ApplicationData.PqcPreKey',
'10': 'prekeys'
},
],
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_Ok$json = {
'1': 'Ok',
@ -1173,6 +1292,15 @@ const Response_Ok$json = {
'9': 0,
'10': 'prekeys'
},
{
'1': 'prekeys_pqc',
'3': 3,
'4': 1,
'5': 11,
'6': '.client_to_server.Response.PqcPrekeys',
'9': 0,
'10': 'prekeysPqc'
},
],
'8': [
{'1': 'Ok'},
@ -1185,5 +1313,8 @@ final $typed_data.Uint8List responseDescriptor = $convert.base64Decode(
'ICb2sSKAoFZXJyb3IYAiABKA4yEC5lcnJvci5FcnJvckNvZGVIAFIFZXJyb3IaMAoGUHJlS2V5'
'Eg4KAmlkGAEgASgDUgJpZBIWCgZwcmVrZXkYAiABKAxSBnByZWtleRpGCgdQcmVrZXlzEjsKB3'
'ByZWtleXMYASADKAsyIS5jbGllbnRfdG9fc2VydmVyLlJlc3BvbnNlLlByZUtleVIHcHJla2V5'
'cxpgCgJPaxIUCgROb25lGAEgASgISABSBE5vbmUSPgoHcHJla2V5cxgCIAEoCzIiLmNsaWVudF'
'90b19zZXJ2ZXIuUmVzcG9uc2UuUHJla2V5c0gAUgdwcmVrZXlzQgQKAk9rQgoKCFJlc3BvbnNl');
'cxpTCgpQcWNQcmVrZXlzEkUKB3ByZWtleXMYASADKAsyKy5jbGllbnRfdG9fc2VydmVyLkFwcG'
'xpY2F0aW9uRGF0YS5QcWNQcmVLZXlSB3ByZWtleXMaqgEKAk9rEhQKBE5vbmUYASABKAhIAFIE'
'Tm9uZRI+CgdwcmVrZXlzGAIgASgLMiIuY2xpZW50X3RvX3NlcnZlci5SZXNwb25zZS5QcmVrZX'
'lzSABSB3ByZWtleXMSSAoLcHJla2V5c19wcWMYAyABKAsyJS5jbGllbnRfdG9fc2VydmVyLlJl'
'c3BvbnNlLlBxY1ByZWtleXNIAFIKcHJla2V5c1BxY0IECgJPa0IKCghSZXNwb25zZQ==');

View file

@ -95,6 +95,7 @@ enum V0_Kind {
requestNewPreKeys,
error,
newMessages,
requestNewPqcPreKeys,
notSet
}
@ -106,6 +107,7 @@ class V0 extends $pb.GeneratedMessage {
$core.bool? requestNewPreKeys,
$0.ErrorCode? error,
NewMessages? newMessages,
$core.bool? requestNewPqcPreKeys,
}) {
final result = create();
if (seq != null) result.seq = seq;
@ -114,6 +116,8 @@ class V0 extends $pb.GeneratedMessage {
if (requestNewPreKeys != null) result.requestNewPreKeys = requestNewPreKeys;
if (error != null) result.error = error;
if (newMessages != null) result.newMessages = newMessages;
if (requestNewPqcPreKeys != null)
result.requestNewPqcPreKeys = requestNewPqcPreKeys;
return result;
}
@ -132,6 +136,7 @@ class V0 extends $pb.GeneratedMessage {
4: V0_Kind.requestNewPreKeys,
6: V0_Kind.error,
7: V0_Kind.newMessages,
8: V0_Kind.requestNewPqcPreKeys,
0: V0_Kind.notSet
};
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
@ -139,7 +144,7 @@ class V0 extends $pb.GeneratedMessage {
package:
const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'),
createEmptyInstance: create)
..oo(0, [2, 3, 4, 6, 7])
..oo(0, [2, 3, 4, 6, 7, 8])
..a<$fixnum.Int64>(1, _omitFieldNames ? '' : 'seq', $pb.PbFieldType.OU6,
defaultOrMaker: $fixnum.Int64.ZERO)
..aOM<Response>(2, _omitFieldNames ? '' : 'response',
@ -152,6 +157,8 @@ class V0 extends $pb.GeneratedMessage {
enumValues: $0.ErrorCode.values)
..aOM<NewMessages>(7, _omitFieldNames ? '' : 'newMessages',
protoName: 'newMessages', subBuilder: NewMessages.create)
..aOB(8, _omitFieldNames ? '' : 'RequestNewPqcPreKeys',
protoName: 'RequestNewPqcPreKeys')
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@ -177,12 +184,14 @@ class V0 extends $pb.GeneratedMessage {
@$pb.TagNumber(4)
@$pb.TagNumber(6)
@$pb.TagNumber(7)
@$pb.TagNumber(8)
V0_Kind whichKind() => _V0_KindByTag[$_whichOneof(0)]!;
@$pb.TagNumber(2)
@$pb.TagNumber(3)
@$pb.TagNumber(4)
@$pb.TagNumber(6)
@$pb.TagNumber(7)
@$pb.TagNumber(8)
void clearKind() => $_clearField($_whichOneof(0));
@$pb.TagNumber(1)
@ -244,6 +253,15 @@ class V0 extends $pb.GeneratedMessage {
void clearNewMessages() => $_clearField(7);
@$pb.TagNumber(7)
NewMessages ensureNewMessages() => $_ensure(5);
@$pb.TagNumber(8)
$core.bool get requestNewPqcPreKeys => $_getBF(6);
@$pb.TagNumber(8)
set requestNewPqcPreKeys($core.bool value) => $_setBool(6, value);
@$pb.TagNumber(8)
$core.bool hasRequestNewPqcPreKeys() => $_has(6);
@$pb.TagNumber(8)
void clearRequestNewPqcPreKeys() => $_clearField(8);
}
class NewMessage extends $pb.GeneratedMessage {
@ -830,45 +848,6 @@ class Response_AdditionalAccount extends $pb.GeneratedMessage {
void clearPlanId() => $_clearField(3);
}
class Response_Deprecated extends $pb.GeneratedMessage {
factory Response_Deprecated() => create();
Response_Deprecated._();
factory Response_Deprecated.fromBuffer($core.List<$core.int> data,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(data, registry);
factory Response_Deprecated.fromJson($core.String json,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(json, registry);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'Response.Deprecated',
package:
const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'),
createEmptyInstance: create)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_Deprecated clone() => deepCopy();
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_Deprecated copyWith(void Function(Response_Deprecated) updates) =>
super.copyWith((message) => updates(message as Response_Deprecated))
as Response_Deprecated;
@$core.override
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Response_Deprecated create() => Response_Deprecated._();
@$core.override
Response_Deprecated createEmptyInstance() => create();
@$core.pragma('dart2js:noInline')
static Response_Deprecated getDefault() => _defaultInstance ??=
$pb.GeneratedMessage.$_defaultFor<Response_Deprecated>(create);
static Response_Deprecated? _defaultInstance;
}
class Response_Transaction extends $pb.GeneratedMessage {
factory Response_Transaction() => create();
@ -1196,6 +1175,252 @@ class Response_SignedPreKey extends $pb.GeneratedMessage {
void clearSignedPrekeySignature() => $_clearField(3);
}
class Response_PqcPreKey extends $pb.GeneratedMessage {
factory Response_PqcPreKey({
$fixnum.Int64? eccPreKeyId,
$core.List<$core.int>? eccPreKey,
$fixnum.Int64? kyberPreKeyId,
$core.List<$core.int>? kyberPreKey,
$core.List<$core.int>? kyberPreKeySignature,
}) {
final result = create();
if (eccPreKeyId != null) result.eccPreKeyId = eccPreKeyId;
if (eccPreKey != null) result.eccPreKey = eccPreKey;
if (kyberPreKeyId != null) result.kyberPreKeyId = kyberPreKeyId;
if (kyberPreKey != null) result.kyberPreKey = kyberPreKey;
if (kyberPreKeySignature != null)
result.kyberPreKeySignature = kyberPreKeySignature;
return result;
}
Response_PqcPreKey._();
factory Response_PqcPreKey.fromBuffer($core.List<$core.int> data,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(data, registry);
factory Response_PqcPreKey.fromJson($core.String json,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(json, registry);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'Response.PqcPreKey',
package:
const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'),
createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'eccPreKeyId')
..a<$core.List<$core.int>>(
2, _omitFieldNames ? '' : 'eccPreKey', $pb.PbFieldType.OY)
..aInt64(3, _omitFieldNames ? '' : 'kyberPreKeyId')
..a<$core.List<$core.int>>(
4, _omitFieldNames ? '' : 'kyberPreKey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(
5, _omitFieldNames ? '' : 'kyberPreKeySignature', $pb.PbFieldType.OY)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_PqcPreKey clone() => deepCopy();
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_PqcPreKey copyWith(void Function(Response_PqcPreKey) updates) =>
super.copyWith((message) => updates(message as Response_PqcPreKey))
as Response_PqcPreKey;
@$core.override
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Response_PqcPreKey create() => Response_PqcPreKey._();
@$core.override
Response_PqcPreKey createEmptyInstance() => create();
@$core.pragma('dart2js:noInline')
static Response_PqcPreKey getDefault() => _defaultInstance ??=
$pb.GeneratedMessage.$_defaultFor<Response_PqcPreKey>(create);
static Response_PqcPreKey? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get eccPreKeyId => $_getI64(0);
@$pb.TagNumber(1)
set eccPreKeyId($fixnum.Int64 value) => $_setInt64(0, value);
@$pb.TagNumber(1)
$core.bool hasEccPreKeyId() => $_has(0);
@$pb.TagNumber(1)
void clearEccPreKeyId() => $_clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get eccPreKey => $_getN(1);
@$pb.TagNumber(2)
set eccPreKey($core.List<$core.int> value) => $_setBytes(1, value);
@$pb.TagNumber(2)
$core.bool hasEccPreKey() => $_has(1);
@$pb.TagNumber(2)
void clearEccPreKey() => $_clearField(2);
@$pb.TagNumber(3)
$fixnum.Int64 get kyberPreKeyId => $_getI64(2);
@$pb.TagNumber(3)
set kyberPreKeyId($fixnum.Int64 value) => $_setInt64(2, value);
@$pb.TagNumber(3)
$core.bool hasKyberPreKeyId() => $_has(2);
@$pb.TagNumber(3)
void clearKyberPreKeyId() => $_clearField(3);
@$pb.TagNumber(4)
$core.List<$core.int> get kyberPreKey => $_getN(3);
@$pb.TagNumber(4)
set kyberPreKey($core.List<$core.int> value) => $_setBytes(3, value);
@$pb.TagNumber(4)
$core.bool hasKyberPreKey() => $_has(3);
@$pb.TagNumber(4)
void clearKyberPreKey() => $_clearField(4);
@$pb.TagNumber(5)
$core.List<$core.int> get kyberPreKeySignature => $_getN(4);
@$pb.TagNumber(5)
set kyberPreKeySignature($core.List<$core.int> value) => $_setBytes(4, value);
@$pb.TagNumber(5)
$core.bool hasKyberPreKeySignature() => $_has(4);
@$pb.TagNumber(5)
void clearKyberPreKeySignature() => $_clearField(5);
}
class Response_PqcBundle extends $pb.GeneratedMessage {
factory Response_PqcBundle({
$fixnum.Int64? eccSignedPrekeyId,
$core.List<$core.int>? eccSignedPrekey,
$core.List<$core.int>? eccSignedPrekeySignature,
$fixnum.Int64? kyberSignedPrekeyId,
$core.List<$core.int>? kyberSignedPrekey,
$core.List<$core.int>? kyberSignedPrekeySignature,
Response_PqcPreKey? prekey,
}) {
final result = create();
if (eccSignedPrekeyId != null) result.eccSignedPrekeyId = eccSignedPrekeyId;
if (eccSignedPrekey != null) result.eccSignedPrekey = eccSignedPrekey;
if (eccSignedPrekeySignature != null)
result.eccSignedPrekeySignature = eccSignedPrekeySignature;
if (kyberSignedPrekeyId != null)
result.kyberSignedPrekeyId = kyberSignedPrekeyId;
if (kyberSignedPrekey != null) result.kyberSignedPrekey = kyberSignedPrekey;
if (kyberSignedPrekeySignature != null)
result.kyberSignedPrekeySignature = kyberSignedPrekeySignature;
if (prekey != null) result.prekey = prekey;
return result;
}
Response_PqcBundle._();
factory Response_PqcBundle.fromBuffer($core.List<$core.int> data,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromBuffer(data, registry);
factory Response_PqcBundle.fromJson($core.String json,
[$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) =>
create()..mergeFromJson(json, registry);
static final $pb.BuilderInfo _i = $pb.BuilderInfo(
_omitMessageNames ? '' : 'Response.PqcBundle',
package:
const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'),
createEmptyInstance: create)
..aInt64(1, _omitFieldNames ? '' : 'eccSignedPrekeyId')
..a<$core.List<$core.int>>(
2, _omitFieldNames ? '' : 'eccSignedPrekey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(3,
_omitFieldNames ? '' : 'eccSignedPrekeySignature', $pb.PbFieldType.OY)
..aInt64(4, _omitFieldNames ? '' : 'kyberSignedPrekeyId')
..a<$core.List<$core.int>>(
5, _omitFieldNames ? '' : 'kyberSignedPrekey', $pb.PbFieldType.OY)
..a<$core.List<$core.int>>(6,
_omitFieldNames ? '' : 'kyberSignedPrekeySignature', $pb.PbFieldType.OY)
..aOM<Response_PqcPreKey>(7, _omitFieldNames ? '' : 'prekey',
subBuilder: Response_PqcPreKey.create)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_PqcBundle clone() => deepCopy();
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
Response_PqcBundle copyWith(void Function(Response_PqcBundle) updates) =>
super.copyWith((message) => updates(message as Response_PqcBundle))
as Response_PqcBundle;
@$core.override
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static Response_PqcBundle create() => Response_PqcBundle._();
@$core.override
Response_PqcBundle createEmptyInstance() => create();
@$core.pragma('dart2js:noInline')
static Response_PqcBundle getDefault() => _defaultInstance ??=
$pb.GeneratedMessage.$_defaultFor<Response_PqcBundle>(create);
static Response_PqcBundle? _defaultInstance;
@$pb.TagNumber(1)
$fixnum.Int64 get eccSignedPrekeyId => $_getI64(0);
@$pb.TagNumber(1)
set eccSignedPrekeyId($fixnum.Int64 value) => $_setInt64(0, value);
@$pb.TagNumber(1)
$core.bool hasEccSignedPrekeyId() => $_has(0);
@$pb.TagNumber(1)
void clearEccSignedPrekeyId() => $_clearField(1);
@$pb.TagNumber(2)
$core.List<$core.int> get eccSignedPrekey => $_getN(1);
@$pb.TagNumber(2)
set eccSignedPrekey($core.List<$core.int> value) => $_setBytes(1, value);
@$pb.TagNumber(2)
$core.bool hasEccSignedPrekey() => $_has(1);
@$pb.TagNumber(2)
void clearEccSignedPrekey() => $_clearField(2);
@$pb.TagNumber(3)
$core.List<$core.int> get eccSignedPrekeySignature => $_getN(2);
@$pb.TagNumber(3)
set eccSignedPrekeySignature($core.List<$core.int> value) =>
$_setBytes(2, value);
@$pb.TagNumber(3)
$core.bool hasEccSignedPrekeySignature() => $_has(2);
@$pb.TagNumber(3)
void clearEccSignedPrekeySignature() => $_clearField(3);
@$pb.TagNumber(4)
$fixnum.Int64 get kyberSignedPrekeyId => $_getI64(3);
@$pb.TagNumber(4)
set kyberSignedPrekeyId($fixnum.Int64 value) => $_setInt64(3, value);
@$pb.TagNumber(4)
$core.bool hasKyberSignedPrekeyId() => $_has(3);
@$pb.TagNumber(4)
void clearKyberSignedPrekeyId() => $_clearField(4);
@$pb.TagNumber(5)
$core.List<$core.int> get kyberSignedPrekey => $_getN(4);
@$pb.TagNumber(5)
set kyberSignedPrekey($core.List<$core.int> value) => $_setBytes(4, value);
@$pb.TagNumber(5)
$core.bool hasKyberSignedPrekey() => $_has(4);
@$pb.TagNumber(5)
void clearKyberSignedPrekey() => $_clearField(5);
@$pb.TagNumber(6)
$core.List<$core.int> get kyberSignedPrekeySignature => $_getN(5);
@$pb.TagNumber(6)
set kyberSignedPrekeySignature($core.List<$core.int> value) =>
$_setBytes(5, value);
@$pb.TagNumber(6)
$core.bool hasKyberSignedPrekeySignature() => $_has(5);
@$pb.TagNumber(6)
void clearKyberSignedPrekeySignature() => $_clearField(6);
@$pb.TagNumber(7)
Response_PqcPreKey get prekey => $_getN(6);
@$pb.TagNumber(7)
set prekey(Response_PqcPreKey value) => $_setField(7, value);
@$pb.TagNumber(7)
$core.bool hasPrekey() => $_has(6);
@$pb.TagNumber(7)
void clearPrekey() => $_clearField(7);
@$pb.TagNumber(7)
Response_PqcPreKey ensurePrekey() => $_ensure(6);
}
class Response_UserData extends $pb.GeneratedMessage {
factory Response_UserData({
$fixnum.Int64? userId,
@ -1206,6 +1431,7 @@ class Response_UserData extends $pb.GeneratedMessage {
$fixnum.Int64? signedPrekeyId,
$core.List<$core.int>? username,
$fixnum.Int64? registrationId,
Response_PqcBundle? pqcBundle,
}) {
final result = create();
if (userId != null) result.userId = userId;
@ -1217,6 +1443,7 @@ class Response_UserData extends $pb.GeneratedMessage {
if (signedPrekeyId != null) result.signedPrekeyId = signedPrekeyId;
if (username != null) result.username = username;
if (registrationId != null) result.registrationId = registrationId;
if (pqcBundle != null) result.pqcBundle = pqcBundle;
return result;
}
@ -1247,6 +1474,8 @@ class Response_UserData extends $pb.GeneratedMessage {
..a<$core.List<$core.int>>(
7, _omitFieldNames ? '' : 'username', $pb.PbFieldType.OY)
..aInt64(8, _omitFieldNames ? '' : 'registrationId')
..aOM<Response_PqcBundle>(9, _omitFieldNames ? '' : 'pqcBundle',
subBuilder: Response_PqcBundle.create)
..hasRequiredFields = false;
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
@ -1334,6 +1563,17 @@ class Response_UserData extends $pb.GeneratedMessage {
$core.bool hasRegistrationId() => $_has(7);
@$pb.TagNumber(8)
void clearRegistrationId() => $_clearField(8);
@$pb.TagNumber(9)
Response_PqcBundle get pqcBundle => $_getN(8);
@$pb.TagNumber(9)
set pqcBundle(Response_PqcBundle value) => $_setField(9, value);
@$pb.TagNumber(9)
$core.bool hasPqcBundle() => $_has(8);
@$pb.TagNumber(9)
void clearPqcBundle() => $_clearField(9);
@$pb.TagNumber(9)
Response_PqcBundle ensurePqcBundle() => $_ensure(8);
}
class Response_UploadToken extends $pb.GeneratedMessage {
@ -2074,11 +2314,9 @@ enum Response_Ok_Ok {
uploadtoken,
userdata,
authtoken,
deprecated7,
authenticated,
plans,
planballance,
deprecated11,
addaccountsinvites,
downloadtokens,
signedprekey,
@ -2100,11 +2338,9 @@ class Response_Ok extends $pb.GeneratedMessage {
Response_UploadToken? uploadtoken,
Response_UserData? userdata,
$core.List<$core.int>? authtoken,
Response_Deprecated? deprecated7,
Response_Authenticated? authenticated,
Response_Plans? plans,
Response_PlanBallance? planballance,
Response_Deprecated? deprecated11,
Response_AddAccountsInvites? addaccountsinvites,
Response_DownloadTokens? downloadtokens,
Response_SignedPreKey? signedprekey,
@ -2123,11 +2359,9 @@ class Response_Ok extends $pb.GeneratedMessage {
if (uploadtoken != null) result.uploadtoken = uploadtoken;
if (userdata != null) result.userdata = userdata;
if (authtoken != null) result.authtoken = authtoken;
if (deprecated7 != null) result.deprecated7 = deprecated7;
if (authenticated != null) result.authenticated = authenticated;
if (plans != null) result.plans = plans;
if (planballance != null) result.planballance = planballance;
if (deprecated11 != null) result.deprecated11 = deprecated11;
if (addaccountsinvites != null)
result.addaccountsinvites = addaccountsinvites;
if (downloadtokens != null) result.downloadtokens = downloadtokens;
@ -2162,11 +2396,9 @@ class Response_Ok extends $pb.GeneratedMessage {
4: Response_Ok_Ok.uploadtoken,
5: Response_Ok_Ok.userdata,
6: Response_Ok_Ok.authtoken,
7: Response_Ok_Ok.deprecated7,
8: Response_Ok_Ok.authenticated,
9: Response_Ok_Ok.plans,
10: Response_Ok_Ok.planballance,
11: Response_Ok_Ok.deprecated11,
12: Response_Ok_Ok.addaccountsinvites,
13: Response_Ok_Ok.downloadtokens,
14: Response_Ok_Ok.signedprekey,
@ -2184,29 +2416,8 @@ class Response_Ok extends $pb.GeneratedMessage {
package:
const $pb.PackageName(_omitMessageNames ? '' : 'server_to_client'),
createEmptyInstance: create)
..oo(0, [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21
])
..oo(
0, [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])
..aOB(1, _omitFieldNames ? '' : 'None', protoName: 'None')
..aInt64(2, _omitFieldNames ? '' : 'userid')
..a<$core.List<$core.int>>(
@ -2217,16 +2428,12 @@ class Response_Ok extends $pb.GeneratedMessage {
subBuilder: Response_UserData.create)
..a<$core.List<$core.int>>(
6, _omitFieldNames ? '' : 'authtoken', $pb.PbFieldType.OY)
..aOM<Response_Deprecated>(7, _omitFieldNames ? '' : 'deprecated7',
protoName: 'deprecated_7', subBuilder: Response_Deprecated.create)
..aOM<Response_Authenticated>(8, _omitFieldNames ? '' : 'authenticated',
subBuilder: Response_Authenticated.create)
..aOM<Response_Plans>(9, _omitFieldNames ? '' : 'plans',
subBuilder: Response_Plans.create)
..aOM<Response_PlanBallance>(10, _omitFieldNames ? '' : 'planballance',
subBuilder: Response_PlanBallance.create)
..aOM<Response_Deprecated>(11, _omitFieldNames ? '' : 'deprecated11',
protoName: 'deprecated_11', subBuilder: Response_Deprecated.create)
..aOM<Response_AddAccountsInvites>(
12, _omitFieldNames ? '' : 'addaccountsinvites',
subBuilder: Response_AddAccountsInvites.create)
@ -2279,11 +2486,9 @@ class Response_Ok extends $pb.GeneratedMessage {
@$pb.TagNumber(4)
@$pb.TagNumber(5)
@$pb.TagNumber(6)
@$pb.TagNumber(7)
@$pb.TagNumber(8)
@$pb.TagNumber(9)
@$pb.TagNumber(10)
@$pb.TagNumber(11)
@$pb.TagNumber(12)
@$pb.TagNumber(13)
@$pb.TagNumber(14)
@ -2301,11 +2506,9 @@ class Response_Ok extends $pb.GeneratedMessage {
@$pb.TagNumber(4)
@$pb.TagNumber(5)
@$pb.TagNumber(6)
@$pb.TagNumber(7)
@$pb.TagNumber(8)
@$pb.TagNumber(9)
@$pb.TagNumber(10)
@$pb.TagNumber(11)
@$pb.TagNumber(12)
@$pb.TagNumber(13)
@$pb.TagNumber(14)
@ -2376,175 +2579,153 @@ class Response_Ok extends $pb.GeneratedMessage {
@$pb.TagNumber(6)
void clearAuthtoken() => $_clearField(6);
@$pb.TagNumber(7)
Response_Deprecated get deprecated7 => $_getN(6);
@$pb.TagNumber(7)
set deprecated7(Response_Deprecated value) => $_setField(7, value);
@$pb.TagNumber(7)
$core.bool hasDeprecated7() => $_has(6);
@$pb.TagNumber(7)
void clearDeprecated7() => $_clearField(7);
@$pb.TagNumber(7)
Response_Deprecated ensureDeprecated7() => $_ensure(6);
@$pb.TagNumber(8)
Response_Authenticated get authenticated => $_getN(7);
Response_Authenticated get authenticated => $_getN(6);
@$pb.TagNumber(8)
set authenticated(Response_Authenticated value) => $_setField(8, value);
@$pb.TagNumber(8)
$core.bool hasAuthenticated() => $_has(7);
$core.bool hasAuthenticated() => $_has(6);
@$pb.TagNumber(8)
void clearAuthenticated() => $_clearField(8);
@$pb.TagNumber(8)
Response_Authenticated ensureAuthenticated() => $_ensure(7);
Response_Authenticated ensureAuthenticated() => $_ensure(6);
@$pb.TagNumber(9)
Response_Plans get plans => $_getN(8);
Response_Plans get plans => $_getN(7);
@$pb.TagNumber(9)
set plans(Response_Plans value) => $_setField(9, value);
@$pb.TagNumber(9)
$core.bool hasPlans() => $_has(8);
$core.bool hasPlans() => $_has(7);
@$pb.TagNumber(9)
void clearPlans() => $_clearField(9);
@$pb.TagNumber(9)
Response_Plans ensurePlans() => $_ensure(8);
Response_Plans ensurePlans() => $_ensure(7);
@$pb.TagNumber(10)
Response_PlanBallance get planballance => $_getN(9);
Response_PlanBallance get planballance => $_getN(8);
@$pb.TagNumber(10)
set planballance(Response_PlanBallance value) => $_setField(10, value);
@$pb.TagNumber(10)
$core.bool hasPlanballance() => $_has(9);
$core.bool hasPlanballance() => $_has(8);
@$pb.TagNumber(10)
void clearPlanballance() => $_clearField(10);
@$pb.TagNumber(10)
Response_PlanBallance ensurePlanballance() => $_ensure(9);
@$pb.TagNumber(11)
Response_Deprecated get deprecated11 => $_getN(10);
@$pb.TagNumber(11)
set deprecated11(Response_Deprecated value) => $_setField(11, value);
@$pb.TagNumber(11)
$core.bool hasDeprecated11() => $_has(10);
@$pb.TagNumber(11)
void clearDeprecated11() => $_clearField(11);
@$pb.TagNumber(11)
Response_Deprecated ensureDeprecated11() => $_ensure(10);
Response_PlanBallance ensurePlanballance() => $_ensure(8);
@$pb.TagNumber(12)
Response_AddAccountsInvites get addaccountsinvites => $_getN(11);
Response_AddAccountsInvites get addaccountsinvites => $_getN(9);
@$pb.TagNumber(12)
set addaccountsinvites(Response_AddAccountsInvites value) =>
$_setField(12, value);
@$pb.TagNumber(12)
$core.bool hasAddaccountsinvites() => $_has(11);
$core.bool hasAddaccountsinvites() => $_has(9);
@$pb.TagNumber(12)
void clearAddaccountsinvites() => $_clearField(12);
@$pb.TagNumber(12)
Response_AddAccountsInvites ensureAddaccountsinvites() => $_ensure(11);
Response_AddAccountsInvites ensureAddaccountsinvites() => $_ensure(9);
@$pb.TagNumber(13)
Response_DownloadTokens get downloadtokens => $_getN(12);
Response_DownloadTokens get downloadtokens => $_getN(10);
@$pb.TagNumber(13)
set downloadtokens(Response_DownloadTokens value) => $_setField(13, value);
@$pb.TagNumber(13)
$core.bool hasDownloadtokens() => $_has(12);
$core.bool hasDownloadtokens() => $_has(10);
@$pb.TagNumber(13)
void clearDownloadtokens() => $_clearField(13);
@$pb.TagNumber(13)
Response_DownloadTokens ensureDownloadtokens() => $_ensure(12);
Response_DownloadTokens ensureDownloadtokens() => $_ensure(10);
@$pb.TagNumber(14)
Response_SignedPreKey get signedprekey => $_getN(13);
Response_SignedPreKey get signedprekey => $_getN(11);
@$pb.TagNumber(14)
set signedprekey(Response_SignedPreKey value) => $_setField(14, value);
@$pb.TagNumber(14)
$core.bool hasSignedprekey() => $_has(13);
$core.bool hasSignedprekey() => $_has(11);
@$pb.TagNumber(14)
void clearSignedprekey() => $_clearField(14);
@$pb.TagNumber(14)
Response_SignedPreKey ensureSignedprekey() => $_ensure(13);
Response_SignedPreKey ensureSignedprekey() => $_ensure(11);
@$pb.TagNumber(15)
Response_ProofOfWork get proofOfWork => $_getN(14);
Response_ProofOfWork get proofOfWork => $_getN(12);
@$pb.TagNumber(15)
set proofOfWork(Response_ProofOfWork value) => $_setField(15, value);
@$pb.TagNumber(15)
$core.bool hasProofOfWork() => $_has(14);
$core.bool hasProofOfWork() => $_has(12);
@$pb.TagNumber(15)
void clearProofOfWork() => $_clearField(15);
@$pb.TagNumber(15)
Response_ProofOfWork ensureProofOfWork() => $_ensure(14);
Response_ProofOfWork ensureProofOfWork() => $_ensure(12);
@$pb.TagNumber(16)
$core.List<$core.int> get passwordlessRecoveryServerKey => $_getN(15);
$core.List<$core.int> get passwordlessRecoveryServerKey => $_getN(13);
@$pb.TagNumber(16)
set passwordlessRecoveryServerKey($core.List<$core.int> value) =>
$_setBytes(15, value);
$_setBytes(13, value);
@$pb.TagNumber(16)
$core.bool hasPasswordlessRecoveryServerKey() => $_has(15);
$core.bool hasPasswordlessRecoveryServerKey() => $_has(13);
@$pb.TagNumber(16)
void clearPasswordlessRecoveryServerKey() => $_clearField(16);
@$pb.TagNumber(17)
Response_PasswordlessNotificationMessages
get passwordlessNotificationMessages => $_getN(16);
get passwordlessNotificationMessages => $_getN(14);
@$pb.TagNumber(17)
set passwordlessNotificationMessages(
Response_PasswordlessNotificationMessages value) =>
$_setField(17, value);
@$pb.TagNumber(17)
$core.bool hasPasswordlessNotificationMessages() => $_has(16);
$core.bool hasPasswordlessNotificationMessages() => $_has(14);
@$pb.TagNumber(17)
void clearPasswordlessNotificationMessages() => $_clearField(17);
@$pb.TagNumber(17)
Response_PasswordlessNotificationMessages
ensurePasswordlessNotificationMessages() => $_ensure(16);
ensurePasswordlessNotificationMessages() => $_ensure(14);
@$pb.TagNumber(18)
Response_MemoriesUploadUrls get memoriesUploadUrls => $_getN(17);
Response_MemoriesUploadUrls get memoriesUploadUrls => $_getN(15);
@$pb.TagNumber(18)
set memoriesUploadUrls(Response_MemoriesUploadUrls value) =>
$_setField(18, value);
@$pb.TagNumber(18)
$core.bool hasMemoriesUploadUrls() => $_has(17);
$core.bool hasMemoriesUploadUrls() => $_has(15);
@$pb.TagNumber(18)
void clearMemoriesUploadUrls() => $_clearField(18);
@$pb.TagNumber(18)
Response_MemoriesUploadUrls ensureMemoriesUploadUrls() => $_ensure(17);
Response_MemoriesUploadUrls ensureMemoriesUploadUrls() => $_ensure(15);
@$pb.TagNumber(19)
Response_MemoriesList get memoriesList => $_getN(18);
Response_MemoriesList get memoriesList => $_getN(16);
@$pb.TagNumber(19)
set memoriesList(Response_MemoriesList value) => $_setField(19, value);
@$pb.TagNumber(19)
$core.bool hasMemoriesList() => $_has(18);
$core.bool hasMemoriesList() => $_has(16);
@$pb.TagNumber(19)
void clearMemoriesList() => $_clearField(19);
@$pb.TagNumber(19)
Response_MemoriesList ensureMemoriesList() => $_ensure(18);
Response_MemoriesList ensureMemoriesList() => $_ensure(16);
@$pb.TagNumber(20)
Response_MemoriesUrl get memoriesUrl => $_getN(19);
Response_MemoriesUrl get memoriesUrl => $_getN(17);
@$pb.TagNumber(20)
set memoriesUrl(Response_MemoriesUrl value) => $_setField(20, value);
@$pb.TagNumber(20)
$core.bool hasMemoriesUrl() => $_has(19);
$core.bool hasMemoriesUrl() => $_has(17);
@$pb.TagNumber(20)
void clearMemoriesUrl() => $_clearField(20);
@$pb.TagNumber(20)
Response_MemoriesUrl ensureMemoriesUrl() => $_ensure(19);
Response_MemoriesUrl ensureMemoriesUrl() => $_ensure(17);
@$pb.TagNumber(21)
Response_MemoriesUsage get memoriesUsage => $_getN(20);
Response_MemoriesUsage get memoriesUsage => $_getN(18);
@$pb.TagNumber(21)
set memoriesUsage(Response_MemoriesUsage value) => $_setField(21, value);
@$pb.TagNumber(21)
$core.bool hasMemoriesUsage() => $_has(20);
$core.bool hasMemoriesUsage() => $_has(18);
@$pb.TagNumber(21)
void clearMemoriesUsage() => $_clearField(21);
@$pb.TagNumber(21)
Response_MemoriesUsage ensureMemoriesUsage() => $_ensure(20);
Response_MemoriesUsage ensureMemoriesUsage() => $_ensure(18);
}
enum Response_Response { ok, error, notSet }

View file

@ -79,6 +79,14 @@ const V0$json = {
'9': 0,
'10': 'RequestNewPreKeys'
},
{
'1': 'RequestNewPqcPreKeys',
'3': 8,
'4': 1,
'5': 8,
'9': 0,
'10': 'RequestNewPqcPreKeys'
},
{
'1': 'error',
'3': 6,
@ -100,8 +108,9 @@ final $typed_data.Uint8List v0Descriptor = $convert.base64Decode(
'llbnQuUmVzcG9uc2VIAFIIcmVzcG9uc2USPgoKbmV3TWVzc2FnZRgDIAEoCzIcLnNlcnZlcl90'
'b19jbGllbnQuTmV3TWVzc2FnZUgAUgpuZXdNZXNzYWdlEkEKC25ld01lc3NhZ2VzGAcgASgLMh'
'0uc2VydmVyX3RvX2NsaWVudC5OZXdNZXNzYWdlc0gAUgtuZXdNZXNzYWdlcxIuChFSZXF1ZXN0'
'TmV3UHJlS2V5cxgEIAEoCEgAUhFSZXF1ZXN0TmV3UHJlS2V5cxIoCgVlcnJvchgGIAEoDjIQLm'
'Vycm9yLkVycm9yQ29kZUgAUgVlcnJvckIGCgRLaW5k');
'TmV3UHJlS2V5cxgEIAEoCEgAUhFSZXF1ZXN0TmV3UHJlS2V5cxI0ChRSZXF1ZXN0TmV3UHFjUH'
'JlS2V5cxgIIAEoCEgAUhRSZXF1ZXN0TmV3UHFjUHJlS2V5cxIoCgVlcnJvchgGIAEoDjIQLmVy'
'cm9yLkVycm9yQ29kZUgAUgVlcnJvckIGCgRLaW5k');
@$core.Deprecated('Use newMessageDescriptor instead')
const NewMessage$json = {
@ -167,11 +176,12 @@ const Response$json = {
Response_AddAccountsInvite$json,
Response_AddAccountsInvites$json,
Response_AdditionalAccount$json,
Response_Deprecated$json,
Response_Transaction$json,
Response_PlanBallance$json,
Response_PreKey$json,
Response_SignedPreKey$json,
Response_PqcPreKey$json,
Response_PqcBundle$json,
Response_UserData$json,
Response_UploadToken$json,
Response_DownloadTokens$json,
@ -306,11 +316,6 @@ const Response_AdditionalAccount$json = {
],
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_Deprecated$json = {
'1': 'Deprecated',
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_Transaction$json = {
'1': 'Transaction',
@ -420,6 +425,86 @@ const Response_SignedPreKey$json = {
],
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_PqcPreKey$json = {
'1': 'PqcPreKey',
'2': [
{'1': 'ecc_pre_key_id', '3': 1, '4': 1, '5': 3, '10': 'eccPreKeyId'},
{'1': 'ecc_pre_key', '3': 2, '4': 1, '5': 12, '10': 'eccPreKey'},
{'1': 'kyber_pre_key_id', '3': 3, '4': 1, '5': 3, '10': 'kyberPreKeyId'},
{'1': 'kyber_pre_key', '3': 4, '4': 1, '5': 12, '10': 'kyberPreKey'},
{
'1': 'kyber_pre_key_signature',
'3': 5,
'4': 1,
'5': 12,
'10': 'kyberPreKeySignature'
},
],
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_PqcBundle$json = {
'1': 'PqcBundle',
'2': [
{
'1': 'ecc_signed_prekey_id',
'3': 1,
'4': 1,
'5': 3,
'10': 'eccSignedPrekeyId'
},
{
'1': 'ecc_signed_prekey',
'3': 2,
'4': 1,
'5': 12,
'10': 'eccSignedPrekey'
},
{
'1': 'ecc_signed_prekey_signature',
'3': 3,
'4': 1,
'5': 12,
'10': 'eccSignedPrekeySignature'
},
{
'1': 'kyber_signed_prekey_id',
'3': 4,
'4': 1,
'5': 3,
'10': 'kyberSignedPrekeyId'
},
{
'1': 'kyber_signed_prekey',
'3': 5,
'4': 1,
'5': 12,
'10': 'kyberSignedPrekey'
},
{
'1': 'kyber_signed_prekey_signature',
'3': 6,
'4': 1,
'5': 12,
'10': 'kyberSignedPrekeySignature'
},
{
'1': 'prekey',
'3': 7,
'4': 1,
'5': 11,
'6': '.server_to_client.Response.PqcPreKey',
'9': 0,
'10': 'prekey',
'17': true
},
],
'8': [
{'1': '_prekey'},
],
};
@$core.Deprecated('Use responseDescriptor instead')
const Response_UserData$json = {
'1': 'UserData',
@ -487,6 +572,16 @@ const Response_UserData$json = {
'10': 'registrationId',
'17': true
},
{
'1': 'pqc_bundle',
'3': 9,
'4': 1,
'5': 11,
'6': '.server_to_client.Response.PqcBundle',
'9': 6,
'10': 'pqcBundle',
'17': true
},
],
'8': [
{'1': '_username'},
@ -495,6 +590,7 @@ const Response_UserData$json = {
{'1': '_signed_prekey_signature'},
{'1': '_signed_prekey_id'},
{'1': '_registration_id'},
{'1': '_pqc_bundle'},
],
};
@ -687,15 +783,6 @@ const Response_Ok$json = {
'10': 'userdata'
},
{'1': 'authtoken', '3': 6, '4': 1, '5': 12, '9': 0, '10': 'authtoken'},
{
'1': 'deprecated_7',
'3': 7,
'4': 1,
'5': 11,
'6': '.server_to_client.Response.Deprecated',
'9': 0,
'10': 'deprecated7'
},
{
'1': 'authenticated',
'3': 8,
@ -723,15 +810,6 @@ const Response_Ok$json = {
'9': 0,
'10': 'planballance'
},
{
'1': 'deprecated_11',
'3': 11,
'4': 1,
'5': 11,
'6': '.server_to_client.Response.Deprecated',
'9': 0,
'10': 'deprecated11'
},
{
'1': 'addaccountsinvites',
'3': 12,
@ -825,6 +903,10 @@ const Response_Ok$json = {
'8': [
{'1': 'Ok'},
],
'9': [
{'1': 7, '2': 8},
{'1': 11, '2': 12},
],
};
/// Descriptor for `Response`. Decode as a `google.protobuf.DescriptorProto`.
@ -846,79 +928,89 @@ final $typed_data.Uint8List responseDescriptor = $convert.base64Decode(
'cGxhbklkEh8KC2ludml0ZV9jb2RlGAIgASgJUgppbnZpdGVDb2RlGlwKEkFkZEFjY291bnRzSW'
'52aXRlcxJGCgdpbnZpdGVzGAEgAygLMiwuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5BZGRB'
'Y2NvdW50c0ludml0ZVIHaW52aXRlcxpFChFBZGRpdGlvbmFsQWNjb3VudBIXCgd1c2VyX2lkGA'
'EgASgDUgZ1c2VySWQSFwoHcGxhbl9pZBgDIAEoCVIGcGxhbklkGgwKCkRlcHJlY2F0ZWQaDQoL'
'VHJhbnNhY3Rpb24alwUKDFBsYW5CYWxsYW5jZRJACh11c2VkX2RhaWx5X21lZGlhX3VwbG9hZF'
'9saW1pdBgBIAEoA1IZdXNlZERhaWx5TWVkaWFVcGxvYWRMaW1pdBI+Chx1c2VkX3VwbG9hZF9t'
'ZWRpYV9zaXplX2xpbWl0GAIgASgDUhh1c2VkVXBsb2FkTWVkaWFTaXplTGltaXQSMwoTcGF5bW'
'VudF9wZXJpb2RfZGF5cxgDIAEoA0gAUhFwYXltZW50UGVyaW9kRGF5c4gBARJLCiBsYXN0X3Bh'
'eW1lbnRfZG9uZV91bml4X3RpbWVzdGFtcBgEIAEoA0gBUhxsYXN0UGF5bWVudERvbmVVbml4VG'
'ltZXN0YW1wiAEBEkoKDHRyYW5zYWN0aW9ucxgFIAMoCzImLnNlcnZlcl90b19jbGllbnQuUmVz'
'cG9uc2UuVHJhbnNhY3Rpb25SDHRyYW5zYWN0aW9ucxJdChNhZGRpdGlvbmFsX2FjY291bnRzGA'
'YgAygLMiwuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5BZGRpdGlvbmFsQWNjb3VudFISYWRk'
'aXRpb25hbEFjY291bnRzEiYKDGF1dG9fcmVuZXdhbBgHIAEoCEgCUgthdXRvUmVuZXdhbIgBAR'
'JCChthZGRpdGlvbmFsX2FjY291bnRfb3duZXJfaWQYCCABKANIA1IYYWRkaXRpb25hbEFjY291'
'bnRPd25lcklkiAEBQhYKFF9wYXltZW50X3BlcmlvZF9kYXlzQiMKIV9sYXN0X3BheW1lbnRfZG'
'9uZV91bml4X3RpbWVzdGFtcEIPCg1fYXV0b19yZW5ld2FsQh4KHF9hZGRpdGlvbmFsX2FjY291'
'bnRfb3duZXJfaWQaMAoGUHJlS2V5Eg4KAmlkGAEgASgDUgJpZBIWCgZwcmVrZXkYAiABKAxSBn'
'ByZWtleRqVAQoMU2lnbmVkUHJlS2V5EigKEHNpZ25lZF9wcmVrZXlfaWQYASABKANSDnNpZ25l'
'ZFByZWtleUlkEiMKDXNpZ25lZF9wcmVrZXkYAiABKAxSDHNpZ25lZFByZWtleRI2ChdzaWduZW'
'RfcHJla2V5X3NpZ25hdHVyZRgDIAEoDFIVc2lnbmVkUHJla2V5U2lnbmF0dXJlGvYDCghVc2Vy'
'RGF0YRIXCgd1c2VyX2lkGAEgASgDUgZ1c2VySWQSOwoHcHJla2V5cxgCIAMoCzIhLnNlcnZlcl'
'90b19jbGllbnQuUmVzcG9uc2UuUHJlS2V5UgdwcmVrZXlzEh8KCHVzZXJuYW1lGAcgASgMSABS'
'CHVzZXJuYW1liAEBEjMKE3B1YmxpY19pZGVudGl0eV9rZXkYAyABKAxIAVIRcHVibGljSWRlbn'
'RpdHlLZXmIAQESKAoNc2lnbmVkX3ByZWtleRgEIAEoDEgCUgxzaWduZWRQcmVrZXmIAQESOwoX'
'c2lnbmVkX3ByZWtleV9zaWduYXR1cmUYBSABKAxIA1IVc2lnbmVkUHJla2V5U2lnbmF0dXJliA'
'EBEi0KEHNpZ25lZF9wcmVrZXlfaWQYBiABKANIBFIOc2lnbmVkUHJla2V5SWSIAQESLAoPcmVn'
'aXN0cmF0aW9uX2lkGAggASgDSAVSDnJlZ2lzdHJhdGlvbklkiAEBQgsKCV91c2VybmFtZUIWCh'
'RfcHVibGljX2lkZW50aXR5X2tleUIQCg5fc2lnbmVkX3ByZWtleUIaChhfc2lnbmVkX3ByZWtl'
'eV9zaWduYXR1cmVCEwoRX3NpZ25lZF9wcmVrZXlfaWRCEgoQX3JlZ2lzdHJhdGlvbl9pZBpZCg'
'tVcGxvYWRUb2tlbhIhCgx1cGxvYWRfdG9rZW4YASABKAxSC3VwbG9hZFRva2VuEicKD2Rvd25s'
'b2FkX3Rva2VucxgCIAMoDFIOZG93bmxvYWRUb2tlbnMaOQoORG93bmxvYWRUb2tlbnMSJwoPZG'
'93bmxvYWRfdG9rZW5zGAEgAygMUg5kb3dubG9hZFRva2VucxpFCgtQcm9vZk9mV29yaxIWCgZw'
'cmVmaXgYASABKAlSBnByZWZpeBIeCgpkaWZmaWN1bHR5GAIgASgDUgpkaWZmaWN1bHR5Gl4KH1'
'Bhc3N3b3JkbGVzc05vdGlmaWNhdGlvbk1lc3NhZ2USDgoCaWQYASABKANSAmlkEisKEWVuY3J5'
'cHRlZF9tZXNzYWdlGAIgASgMUhBlbmNyeXB0ZWRNZXNzYWdlGnoKIFBhc3N3b3JkbGVzc05vdG'
'lmaWNhdGlvbk1lc3NhZ2VzElYKCG1lc3NhZ2VzGAEgAygLMjouc2VydmVyX3RvX2NsaWVudC5S'
'ZXNwb25zZS5QYXNzd29yZGxlc3NOb3RpZmljYXRpb25NZXNzYWdlUghtZXNzYWdlcxqqAQoNUH'
'Jlc2lnbmVkUG9zdBIQCgN1cmwYASABKAlSA3VybBJMCgZmaWVsZHMYAiADKAsyNC5zZXJ2ZXJf'
'dG9fY2xpZW50LlJlc3BvbnNlLlByZXNpZ25lZFBvc3QuRmllbGRzRW50cnlSBmZpZWxkcxo5Cg'
'tGaWVsZHNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoCVIFdmFsdWU6AjgB'
'Gs8BChJNZW1vcmllc1VwbG9hZFVybHMSGQoIbWVkaWFfaWQYASABKAlSB21lZGlhSWQSUwoQdG'
'h1bWJuYWlsX3VwbG9hZBgCIAEoCzIoLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuUHJlc2ln'
'bmVkUG9zdFIPdGh1bWJuYWlsVXBsb2FkEkkKC2Z1bGxfdXBsb2FkGAMgASgLMiguc2VydmVyX3'
'RvX2NsaWVudC5SZXNwb25zZS5QcmVzaWduZWRQb3N0UgpmdWxsVXBsb2FkGoEBCglNZWRpYUl0'
'ZW0SGQoIbWVkaWFfaWQYASABKAlSB21lZGlhSWQSIwoNb3JpZ2luYWxfZGF0ZRgCIAEoA1IMb3'
'JpZ2luYWxEYXRlEjQKFnRodW1ibmFpbF9kb3dubG9hZF91cmwYAyABKAlSFHRodW1ibmFpbERv'
'd25sb2FkVXJsGkoKDE1lbW9yaWVzTGlzdBI6CgVpdGVtcxgBIAMoCzIkLnNlcnZlcl90b19jbG'
'llbnQuUmVzcG9uc2UuTWVkaWFJdGVtUgVpdGVtcxo5CgtNZW1vcmllc1VybBIqChFmdWxsX2Rv'
'd25sb2FkX3VybBgBIAEoCVIPZnVsbERvd25sb2FkVXJsGmcKDU1lbW9yaWVzVXNhZ2USGwoJbW'
'F4X2J5dGVzGAEgASgDUghtYXhCeXRlcxIjCg1jdXJyZW50X2J5dGVzGAIgASgDUgxjdXJyZW50'
'Qnl0ZXMSFAoFY291bnQYAyABKANSBWNvdW50GoMMCgJPaxIUCgROb25lGAEgASgISABSBE5vbm'
'USGAoGdXNlcmlkGAIgASgDSABSBnVzZXJpZBImCg1hdXRoY2hhbGxlbmdlGAMgASgMSABSDWF1'
'dGhjaGFsbGVuZ2USSgoLdXBsb2FkdG9rZW4YBCABKAsyJi5zZXJ2ZXJfdG9fY2xpZW50LlJlc3'
'BvbnNlLlVwbG9hZFRva2VuSABSC3VwbG9hZHRva2VuEkEKCHVzZXJkYXRhGAUgASgLMiMuc2Vy'
'dmVyX3RvX2NsaWVudC5SZXNwb25zZS5Vc2VyRGF0YUgAUgh1c2VyZGF0YRIeCglhdXRodG9rZW'
'4YBiABKAxIAFIJYXV0aHRva2VuEkoKDGRlcHJlY2F0ZWRfNxgHIAEoCzIlLnNlcnZlcl90b19j'
'bGllbnQuUmVzcG9uc2UuRGVwcmVjYXRlZEgAUgtkZXByZWNhdGVkNxJQCg1hdXRoZW50aWNhdG'
'VkGAggASgLMiguc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5BdXRoZW50aWNhdGVkSABSDWF1'
'dGhlbnRpY2F0ZWQSOAoFcGxhbnMYCSABKAsyIC5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLl'
'BsYW5zSABSBXBsYW5zEk0KDHBsYW5iYWxsYW5jZRgKIAEoCzInLnNlcnZlcl90b19jbGllbnQu'
'UmVzcG9uc2UuUGxhbkJhbGxhbmNlSABSDHBsYW5iYWxsYW5jZRJMCg1kZXByZWNhdGVkXzExGA'
'sgASgLMiUuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5EZXByZWNhdGVkSABSDGRlcHJlY2F0'
'ZWQxMRJfChJhZGRhY2NvdW50c2ludml0ZXMYDCABKAsyLS5zZXJ2ZXJfdG9fY2xpZW50LlJlc3'
'BvbnNlLkFkZEFjY291bnRzSW52aXRlc0gAUhJhZGRhY2NvdW50c2ludml0ZXMSUwoOZG93bmxv'
'YWR0b2tlbnMYDSABKAsyKS5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLkRvd25sb2FkVG9rZW'
'5zSABSDmRvd25sb2FkdG9rZW5zEk0KDHNpZ25lZHByZWtleRgOIAEoCzInLnNlcnZlcl90b19j'
'bGllbnQuUmVzcG9uc2UuU2lnbmVkUHJlS2V5SABSDHNpZ25lZHByZWtleRJKCgtwcm9vZk9mV2'
'9yaxgPIAEoCzImLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuUHJvb2ZPZldvcmtIAFILcHJv'
'b2ZPZldvcmsSSQogcGFzc3dvcmRsZXNzX3JlY292ZXJ5X3NlcnZlcl9rZXkYECABKAxIAFIdcG'
'Fzc3dvcmRsZXNzUmVjb3ZlcnlTZXJ2ZXJLZXkSiwEKInBhc3N3b3JkbGVzc19ub3RpZmljYXRp'
'b25fbWVzc2FnZXMYESABKAsyOy5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlBhc3N3b3JkbG'
'Vzc05vdGlmaWNhdGlvbk1lc3NhZ2VzSABSIHBhc3N3b3JkbGVzc05vdGlmaWNhdGlvbk1lc3Nh'
'Z2VzEmEKFG1lbW9yaWVzX3VwbG9hZF91cmxzGBIgASgLMi0uc2VydmVyX3RvX2NsaWVudC5SZX'
'Nwb25zZS5NZW1vcmllc1VwbG9hZFVybHNIAFISbWVtb3JpZXNVcGxvYWRVcmxzEk4KDW1lbW9y'
'aWVzX2xpc3QYEyABKAsyJy5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLk1lbW9yaWVzTGlzdE'
'gAUgxtZW1vcmllc0xpc3QSSwoMbWVtb3JpZXNfdXJsGBQgASgLMiYuc2VydmVyX3RvX2NsaWVu'
'dC5SZXNwb25zZS5NZW1vcmllc1VybEgAUgttZW1vcmllc1VybBJRCg5tZW1vcmllc191c2FnZR'
'gVIAEoCzIoLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuTWVtb3JpZXNVc2FnZUgAUg1tZW1v'
'cmllc1VzYWdlQgQKAk9rQgoKCFJlc3BvbnNl');
'EgASgDUgZ1c2VySWQSFwoHcGxhbl9pZBgDIAEoCVIGcGxhbklkGg0KC1RyYW5zYWN0aW9uGpcF'
'CgxQbGFuQmFsbGFuY2USQAoddXNlZF9kYWlseV9tZWRpYV91cGxvYWRfbGltaXQYASABKANSGX'
'VzZWREYWlseU1lZGlhVXBsb2FkTGltaXQSPgocdXNlZF91cGxvYWRfbWVkaWFfc2l6ZV9saW1p'
'dBgCIAEoA1IYdXNlZFVwbG9hZE1lZGlhU2l6ZUxpbWl0EjMKE3BheW1lbnRfcGVyaW9kX2RheX'
'MYAyABKANIAFIRcGF5bWVudFBlcmlvZERheXOIAQESSwogbGFzdF9wYXltZW50X2RvbmVfdW5p'
'eF90aW1lc3RhbXAYBCABKANIAVIcbGFzdFBheW1lbnREb25lVW5peFRpbWVzdGFtcIgBARJKCg'
'x0cmFuc2FjdGlvbnMYBSADKAsyJi5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlRyYW5zYWN0'
'aW9uUgx0cmFuc2FjdGlvbnMSXQoTYWRkaXRpb25hbF9hY2NvdW50cxgGIAMoCzIsLnNlcnZlcl'
'90b19jbGllbnQuUmVzcG9uc2UuQWRkaXRpb25hbEFjY291bnRSEmFkZGl0aW9uYWxBY2NvdW50'
'cxImCgxhdXRvX3JlbmV3YWwYByABKAhIAlILYXV0b1JlbmV3YWyIAQESQgobYWRkaXRpb25hbF'
'9hY2NvdW50X293bmVyX2lkGAggASgDSANSGGFkZGl0aW9uYWxBY2NvdW50T3duZXJJZIgBAUIW'
'ChRfcGF5bWVudF9wZXJpb2RfZGF5c0IjCiFfbGFzdF9wYXltZW50X2RvbmVfdW5peF90aW1lc3'
'RhbXBCDwoNX2F1dG9fcmVuZXdhbEIeChxfYWRkaXRpb25hbF9hY2NvdW50X293bmVyX2lkGjAK'
'BlByZUtleRIOCgJpZBgBIAEoA1ICaWQSFgoGcHJla2V5GAIgASgMUgZwcmVrZXkalQEKDFNpZ2'
'5lZFByZUtleRIoChBzaWduZWRfcHJla2V5X2lkGAEgASgDUg5zaWduZWRQcmVrZXlJZBIjCg1z'
'aWduZWRfcHJla2V5GAIgASgMUgxzaWduZWRQcmVrZXkSNgoXc2lnbmVkX3ByZWtleV9zaWduYX'
'R1cmUYAyABKAxSFXNpZ25lZFByZWtleVNpZ25hdHVyZRrUAQoJUHFjUHJlS2V5EiMKDmVjY19w'
'cmVfa2V5X2lkGAEgASgDUgtlY2NQcmVLZXlJZBIeCgtlY2NfcHJlX2tleRgCIAEoDFIJZWNjUH'
'JlS2V5EicKEGt5YmVyX3ByZV9rZXlfaWQYAyABKANSDWt5YmVyUHJlS2V5SWQSIgoNa3liZXJf'
'cHJlX2tleRgEIAEoDFILa3liZXJQcmVLZXkSNQoXa3liZXJfcHJlX2tleV9zaWduYXR1cmUYBS'
'ABKAxSFGt5YmVyUHJlS2V5U2lnbmF0dXJlGp0DCglQcWNCdW5kbGUSLwoUZWNjX3NpZ25lZF9w'
'cmVrZXlfaWQYASABKANSEWVjY1NpZ25lZFByZWtleUlkEioKEWVjY19zaWduZWRfcHJla2V5GA'
'IgASgMUg9lY2NTaWduZWRQcmVrZXkSPQobZWNjX3NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlGAMg'
'ASgMUhhlY2NTaWduZWRQcmVrZXlTaWduYXR1cmUSMwoWa3liZXJfc2lnbmVkX3ByZWtleV9pZB'
'gEIAEoA1ITa3liZXJTaWduZWRQcmVrZXlJZBIuChNreWJlcl9zaWduZWRfcHJla2V5GAUgASgM'
'UhFreWJlclNpZ25lZFByZWtleRJBCh1reWJlcl9zaWduZWRfcHJla2V5X3NpZ25hdHVyZRgGIA'
'EoDFIaa3liZXJTaWduZWRQcmVrZXlTaWduYXR1cmUSQQoGcHJla2V5GAcgASgLMiQuc2VydmVy'
'X3RvX2NsaWVudC5SZXNwb25zZS5QcWNQcmVLZXlIAFIGcHJla2V5iAEBQgkKB19wcmVrZXkazw'
'QKCFVzZXJEYXRhEhcKB3VzZXJfaWQYASABKANSBnVzZXJJZBI7CgdwcmVrZXlzGAIgAygLMiEu'
'c2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5QcmVLZXlSB3ByZWtleXMSHwoIdXNlcm5hbWUYBy'
'ABKAxIAFIIdXNlcm5hbWWIAQESMwoTcHVibGljX2lkZW50aXR5X2tleRgDIAEoDEgBUhFwdWJs'
'aWNJZGVudGl0eUtleYgBARIoCg1zaWduZWRfcHJla2V5GAQgASgMSAJSDHNpZ25lZFByZWtleY'
'gBARI7ChdzaWduZWRfcHJla2V5X3NpZ25hdHVyZRgFIAEoDEgDUhVzaWduZWRQcmVrZXlTaWdu'
'YXR1cmWIAQESLQoQc2lnbmVkX3ByZWtleV9pZBgGIAEoA0gEUg5zaWduZWRQcmVrZXlJZIgBAR'
'IsCg9yZWdpc3RyYXRpb25faWQYCCABKANIBVIOcmVnaXN0cmF0aW9uSWSIAQESSAoKcHFjX2J1'
'bmRsZRgJIAEoCzIkLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuUHFjQnVuZGxlSAZSCXBxY0'
'J1bmRsZYgBAUILCglfdXNlcm5hbWVCFgoUX3B1YmxpY19pZGVudGl0eV9rZXlCEAoOX3NpZ25l'
'ZF9wcmVrZXlCGgoYX3NpZ25lZF9wcmVrZXlfc2lnbmF0dXJlQhMKEV9zaWduZWRfcHJla2V5X2'
'lkQhIKEF9yZWdpc3RyYXRpb25faWRCDQoLX3BxY19idW5kbGUaWQoLVXBsb2FkVG9rZW4SIQoM'
'dXBsb2FkX3Rva2VuGAEgASgMUgt1cGxvYWRUb2tlbhInCg9kb3dubG9hZF90b2tlbnMYAiADKA'
'xSDmRvd25sb2FkVG9rZW5zGjkKDkRvd25sb2FkVG9rZW5zEicKD2Rvd25sb2FkX3Rva2VucxgB'
'IAMoDFIOZG93bmxvYWRUb2tlbnMaRQoLUHJvb2ZPZldvcmsSFgoGcHJlZml4GAEgASgJUgZwcm'
'VmaXgSHgoKZGlmZmljdWx0eRgCIAEoA1IKZGlmZmljdWx0eRpeCh9QYXNzd29yZGxlc3NOb3Rp'
'ZmljYXRpb25NZXNzYWdlEg4KAmlkGAEgASgDUgJpZBIrChFlbmNyeXB0ZWRfbWVzc2FnZRgCIA'
'EoDFIQZW5jcnlwdGVkTWVzc2FnZRp6CiBQYXNzd29yZGxlc3NOb3RpZmljYXRpb25NZXNzYWdl'
'cxJWCghtZXNzYWdlcxgBIAMoCzI6LnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuUGFzc3dvcm'
'RsZXNzTm90aWZpY2F0aW9uTWVzc2FnZVIIbWVzc2FnZXMaqgEKDVByZXNpZ25lZFBvc3QSEAoD'
'dXJsGAEgASgJUgN1cmwSTAoGZmllbGRzGAIgAygLMjQuc2VydmVyX3RvX2NsaWVudC5SZXNwb2'
'5zZS5QcmVzaWduZWRQb3N0LkZpZWxkc0VudHJ5UgZmaWVsZHMaOQoLRmllbGRzRW50cnkSEAoD'
'a2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4ARrPAQoSTWVtb3JpZXNVcG'
'xvYWRVcmxzEhkKCG1lZGlhX2lkGAEgASgJUgdtZWRpYUlkElMKEHRodW1ibmFpbF91cGxvYWQY'
'AiABKAsyKC5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlByZXNpZ25lZFBvc3RSD3RodW1ibm'
'FpbFVwbG9hZBJJCgtmdWxsX3VwbG9hZBgDIAEoCzIoLnNlcnZlcl90b19jbGllbnQuUmVzcG9u'
'c2UuUHJlc2lnbmVkUG9zdFIKZnVsbFVwbG9hZBqBAQoJTWVkaWFJdGVtEhkKCG1lZGlhX2lkGA'
'EgASgJUgdtZWRpYUlkEiMKDW9yaWdpbmFsX2RhdGUYAiABKANSDG9yaWdpbmFsRGF0ZRI0ChZ0'
'aHVtYm5haWxfZG93bmxvYWRfdXJsGAMgASgJUhR0aHVtYm5haWxEb3dubG9hZFVybBpKCgxNZW'
'1vcmllc0xpc3QSOgoFaXRlbXMYASADKAsyJC5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLk1l'
'ZGlhSXRlbVIFaXRlbXMaOQoLTWVtb3JpZXNVcmwSKgoRZnVsbF9kb3dubG9hZF91cmwYASABKA'
'lSD2Z1bGxEb3dubG9hZFVybBpnCg1NZW1vcmllc1VzYWdlEhsKCW1heF9ieXRlcxgBIAEoA1II'
'bWF4Qnl0ZXMSIwoNY3VycmVudF9ieXRlcxgCIAEoA1IMY3VycmVudEJ5dGVzEhQKBWNvdW50GA'
'MgASgDUgVjb3VudBr1CgoCT2sSFAoETm9uZRgBIAEoCEgAUgROb25lEhgKBnVzZXJpZBgCIAEo'
'A0gAUgZ1c2VyaWQSJgoNYXV0aGNoYWxsZW5nZRgDIAEoDEgAUg1hdXRoY2hhbGxlbmdlEkoKC3'
'VwbG9hZHRva2VuGAQgASgLMiYuc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS5VcGxvYWRUb2tl'
'bkgAUgt1cGxvYWR0b2tlbhJBCgh1c2VyZGF0YRgFIAEoCzIjLnNlcnZlcl90b19jbGllbnQuUm'
'VzcG9uc2UuVXNlckRhdGFIAFIIdXNlcmRhdGESHgoJYXV0aHRva2VuGAYgASgMSABSCWF1dGh0'
'b2tlbhJQCg1hdXRoZW50aWNhdGVkGAggASgLMiguc2VydmVyX3RvX2NsaWVudC5SZXNwb25zZS'
'5BdXRoZW50aWNhdGVkSABSDWF1dGhlbnRpY2F0ZWQSOAoFcGxhbnMYCSABKAsyIC5zZXJ2ZXJf'
'dG9fY2xpZW50LlJlc3BvbnNlLlBsYW5zSABSBXBsYW5zEk0KDHBsYW5iYWxsYW5jZRgKIAEoCz'
'InLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuUGxhbkJhbGxhbmNlSABSDHBsYW5iYWxsYW5j'
'ZRJfChJhZGRhY2NvdW50c2ludml0ZXMYDCABKAsyLS5zZXJ2ZXJfdG9fY2xpZW50LlJlc3Bvbn'
'NlLkFkZEFjY291bnRzSW52aXRlc0gAUhJhZGRhY2NvdW50c2ludml0ZXMSUwoOZG93bmxvYWR0'
'b2tlbnMYDSABKAsyKS5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLkRvd25sb2FkVG9rZW5zSA'
'BSDmRvd25sb2FkdG9rZW5zEk0KDHNpZ25lZHByZWtleRgOIAEoCzInLnNlcnZlcl90b19jbGll'
'bnQuUmVzcG9uc2UuU2lnbmVkUHJlS2V5SABSDHNpZ25lZHByZWtleRJKCgtwcm9vZk9mV29yax'
'gPIAEoCzImLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuUHJvb2ZPZldvcmtIAFILcHJvb2ZP'
'ZldvcmsSSQogcGFzc3dvcmRsZXNzX3JlY292ZXJ5X3NlcnZlcl9rZXkYECABKAxIAFIdcGFzc3'
'dvcmRsZXNzUmVjb3ZlcnlTZXJ2ZXJLZXkSiwEKInBhc3N3b3JkbGVzc19ub3RpZmljYXRpb25f'
'bWVzc2FnZXMYESABKAsyOy5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLlBhc3N3b3JkbGVzc0'
'5vdGlmaWNhdGlvbk1lc3NhZ2VzSABSIHBhc3N3b3JkbGVzc05vdGlmaWNhdGlvbk1lc3NhZ2Vz'
'EmEKFG1lbW9yaWVzX3VwbG9hZF91cmxzGBIgASgLMi0uc2VydmVyX3RvX2NsaWVudC5SZXNwb2'
'5zZS5NZW1vcmllc1VwbG9hZFVybHNIAFISbWVtb3JpZXNVcGxvYWRVcmxzEk4KDW1lbW9yaWVz'
'X2xpc3QYEyABKAsyJy5zZXJ2ZXJfdG9fY2xpZW50LlJlc3BvbnNlLk1lbW9yaWVzTGlzdEgAUg'
'xtZW1vcmllc0xpc3QSSwoMbWVtb3JpZXNfdXJsGBQgASgLMiYuc2VydmVyX3RvX2NsaWVudC5S'
'ZXNwb25zZS5NZW1vcmllc1VybEgAUgttZW1vcmllc1VybBJRCg5tZW1vcmllc191c2FnZRgVIA'
'EoCzIoLnNlcnZlcl90b19jbGllbnQuUmVzcG9uc2UuTWVtb3JpZXNVc2FnZUgAUg1tZW1vcmll'
'c1VzYWdlQgQKAk9rSgQIBxAISgQICxAMQgoKCFJlc3BvbnNl');

View file

@ -25,6 +25,8 @@ class Message_Type extends $pb.ProtobufEnum {
Message_Type._(3, _omitEnumNames ? '' : 'PREKEY_BUNDLE');
static const Message_Type TEST_NOTIFICATION =
Message_Type._(4, _omitEnumNames ? '' : 'TEST_NOTIFICATION');
static const Message_Type CIPHERTEXT_V2 =
Message_Type._(5, _omitEnumNames ? '' : 'CIPHERTEXT_V2');
static const $core.List<Message_Type> values = <Message_Type>[
SENDER_DELIVERY_RECEIPT,
@ -32,10 +34,11 @@ class Message_Type extends $pb.ProtobufEnum {
CIPHERTEXT,
PREKEY_BUNDLE,
TEST_NOTIFICATION,
CIPHERTEXT_V2,
];
static final $core.List<Message_Type?> _byValue =
$pb.ProtobufEnum.$_initByValueList(values, 4);
$pb.ProtobufEnum.$_initByValueList(values, 5);
static Message_Type? valueOf($core.int value) =>
value < 0 || value >= _byValue.length ? null : _byValue[value];

View file

@ -57,6 +57,7 @@ const Message_Type$json = {
{'1': 'CIPHERTEXT', '2': 2},
{'1': 'PREKEY_BUNDLE', '2': 3},
{'1': 'TEST_NOTIFICATION', '2': 4},
{'1': 'CIPHERTEXT_V2', '2': 5},
],
};
@ -65,10 +66,10 @@ final $typed_data.Uint8List messageDescriptor = $convert.base64Decode(
'CgdNZXNzYWdlEiEKBHR5cGUYASABKA4yDS5NZXNzYWdlLlR5cGVSBHR5cGUSHQoKcmVjZWlwdF'
'9pZBgCIAEoCVIJcmVjZWlwdElkEjAKEWVuY3J5cHRlZF9jb250ZW50GAMgASgMSABSEGVuY3J5'
'cHRlZENvbnRlbnSIAQESQwoRcGxhaW50ZXh0X2NvbnRlbnQYBCABKAsyES5QbGFpbnRleHRDb2'
'50ZW50SAFSEHBsYWludGV4dENvbnRlbnSIAQEidAoEVHlwZRIbChdTRU5ERVJfREVMSVZFUllf'
'UkVDRUlQVBAAEhUKEVBMQUlOVEVYVF9DT05URU5UEAESDgoKQ0lQSEVSVEVYVBACEhEKDVBSRU'
'tFWV9CVU5ETEUQAxIVChFURVNUX05PVElGSUNBVElPThAEQhQKEl9lbmNyeXB0ZWRfY29udGVu'
'dEIUChJfcGxhaW50ZXh0X2NvbnRlbnQ=');
'50ZW50SAFSEHBsYWludGV4dENvbnRlbnSIAQEihwEKBFR5cGUSGwoXU0VOREVSX0RFTElWRVJZ'
'X1JFQ0VJUFQQABIVChFQTEFJTlRFWFRfQ09OVEVOVBABEg4KCkNJUEhFUlRFWFQQAhIRCg1QUk'
'VLRVlfQlVORExFEAMSFQoRVEVTVF9OT1RJRklDQVRJT04QBBIRCg1DSVBIRVJURVhUX1YyEAVC'
'FAoSX2VuY3J5cHRlZF9jb250ZW50QhQKEl9wbGFpbnRleHRfY29udGVudA==');
@$core.Deprecated('Use plaintextContentDescriptor instead')
const PlaintextContent$json = {

View file

@ -7,6 +7,7 @@ message Message {
CIPHERTEXT = 2;
PREKEY_BUNDLE = 3;
TEST_NOTIFICATION = 4;
CIPHERTEXT_V2 = 5;
}
Type type = 1;
string receipt_id = 2;

View file

@ -19,6 +19,8 @@ import 'package:twonly/core/bridge/wrapper/key_manager.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pb.dart'
as client;
import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pbserver.dart';
import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart';
import 'package:twonly/src/model/protobuf/api/websocket/server_to_client.pb.dart'
@ -625,7 +627,13 @@ class ApiService {
final signalStore = await getSignalStoreFromIdentity(signalIdentity);
final signedPreKey = (await signalStore.loadSignedPreKeys())[0];
final signedPreKeysList = await signalStore.loadSignedPreKeys();
if (signedPreKeysList.isEmpty) {
throw Exception(
'Signal Signed PreKeys list is empty. Database insertion likely failed due to lack of storage space or a corrupted database.',
);
}
final signedPreKey = signedPreKeysList[0];
final loginToken = await RustKeyManager.getLoginToken();
@ -992,6 +1000,28 @@ class ApiService {
return sendRequestSync(req);
}
Future<Result> uploadPqcPreKeys(
int eccSignedPreKeyId,
Uint8List eccSignedPreKey,
Uint8List eccSignedPreKeySignature,
int kyberSignedPreKeyId,
Uint8List kyberSignedPreKey,
Uint8List kyberSignedPreKeySignature,
List<client.ApplicationData_PqcPreKey> prekeys,
) async {
final get = ApplicationData_UploadPqcPreKeys()
..eccSignedPrekeyId = Int64(eccSignedPreKeyId)
..eccSignedPrekey = eccSignedPreKey
..eccSignedPrekeySignature = eccSignedPreKeySignature
..kyberSignedPrekeyId = Int64(kyberSignedPreKeyId)
..kyberSignedPrekey = kyberSignedPreKey
..kyberSignedPrekeySignature = kyberSignedPreKeySignature
..prekeys.addAll(prekeys);
final appData = ApplicationData()..uploadPqcPrekeys = get;
final req = createClientToServerFromApplicationData(appData);
return sendRequestSync(req);
}
Future<Response_PlanBallance?> loadPlanBalance({bool useCache = true}) async {
final ballance = await getPlanBallance();
if (ballance != null) {

View file

@ -1,4 +1,5 @@
import 'package:fixnum/fixnum.dart';
import 'package:twonly/core/bridge/wrapper/signal.dart';
import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pb.dart'
as client;
import 'package:twonly/src/services/signal/identity.signal.dart';
@ -18,3 +19,25 @@ Future<client.Response> handleRequestNewPreKey() async {
final ok = client.Response_Ok()..prekeys = prekeys;
return client.Response()..ok = ok;
}
Future<client.Response?> handleRequestNewPqcPreKey() async {
final pqcKeys = await RustSignal.generatePqcPrekeys();
if (pqcKeys.isEmpty) return null;
final prekeysList = <client.ApplicationData_PqcPreKey>[];
for (final pqcKey in pqcKeys) {
prekeysList.add(
client.ApplicationData_PqcPreKey(
eccPreKeyId: Int64(pqcKey.eccPreKeyId),
eccPreKey: pqcKey.eccPreKey,
kyberPreKeyId: Int64(pqcKey.kyberPreKeyId),
kyberPreKey: pqcKey.kyberPreKey,
kyberPreKeySignature: pqcKey.kyberPreKeySignature,
),
);
}
final prekeys = client.Response_PqcPrekeys(prekeys: prekeysList);
final ok = client.Response_Ok()..prekeysPqc = prekeys;
return client.Response()..ok = ok;
}

View file

@ -5,10 +5,10 @@ import 'dart:io';
import 'package:clock/clock.dart';
import 'package:drift/drift.dart';
import 'package:fixnum/fixnum.dart';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:mutex/mutex.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/tables/contacts.table.dart';
import 'package:twonly/src/database/tables/messages.table.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart';
@ -176,11 +176,11 @@ Future<(Uint8List, Uint8List?)?> _tryToSendCompleteMessageInternal({
}
if (message.type == pb.Message_Type.CIPHERTEXT) {
final cipherText = await signalEncryptMessage(
final encryptResult = await signalEncryptMessage(
receipt.contactId,
Uint8List.fromList(message.encryptedContent),
);
if (cipherText == null) {
if (encryptResult == null) {
Log.error(
'[${receipt.receiptId}] Could not encrypt the message for user ${receipt.contactId}. Aborting and trying again.',
);
@ -194,16 +194,31 @@ Future<(Uint8List, Uint8List?)?> _tryToSendCompleteMessageInternal({
await twonlyDB.receiptsDao.deleteReceipt(receipt.receiptId);
return null;
}
message.encryptedContent = cipherText.serialize();
switch (cipherText.getType()) {
case CiphertextMessage.prekeyType:
message.type = pb.Message_Type.PREKEY_BUNDLE;
case CiphertextMessage.whisperType:
message.type = pb.Message_Type.CIPHERTEXT;
default:
Log.error('Invalid ciphertext type: ${cipherText.getType()}.');
message
..encryptedContent = encryptResult.ciphertext
..type = encryptResult.type;
} else if (message.type == pb.Message_Type.CIPHERTEXT_V2) {
final encryptResult = await signalEncryptMessageV2(
receipt.contactId,
Uint8List.fromList(message.encryptedContent),
);
if (encryptResult == null) {
Log.error(
'[${receipt.receiptId}] Could not encrypt the message (V2) for user ${receipt.contactId}. Aborting and trying again.',
);
if (receipt.messageId != null) {
await twonlyDB.messagesDao.handleMessageAckByServer(
receipt.contactId,
receipt.messageId!,
clock.now(),
);
}
await twonlyDB.receiptsDao.deleteReceipt(receipt.receiptId);
return null;
}
message
..encryptedContent = encryptResult.ciphertext
..type = encryptResult.type;
}
if (onlyReturnEncryptedData) {
@ -482,8 +497,11 @@ Future<(Uint8List, Uint8List?)?> sendCipherText(
}
}
final contact = await twonlyDB.contactsDao.getContactById(contactId);
final isV2 = contact?.signalVersion == SignalVersion.v2;
final response = pb.Message()
..type = pb.Message_Type.CIPHERTEXT
..type = isV2 ? pb.Message_Type.CIPHERTEXT_V2 : pb.Message_Type.CIPHERTEXT
..encryptedContent = encryptedContent.writeToBuffer();
var retryCounter = 0;

View file

@ -49,6 +49,8 @@ Future<void> handleServerMessage(server.ServerToClient msg) async {
try {
if (msg.v0.hasRequestNewPreKeys()) {
response = await handleRequestNewPreKey();
} else if (msg.v0.hasRequestNewPqcPreKeys()) {
response = (await handleRequestNewPqcPreKey()) ?? response;
} else if (msg.v0.hasNewMessage()) {
Log.info('Got 1 message from the server.');
await handleClient2ClientMessage(msg.v0.newMessage);
@ -190,6 +192,7 @@ Future<void> _handleClient2ClientMessage(
}
case Message_Type.CIPHERTEXT:
case Message_Type.CIPHERTEXT_V2:
case Message_Type.PREKEY_BUNDLE:
if (message.hasEncryptedContent()) {
Value<String>? receiptIdDB;
@ -297,12 +300,23 @@ Future<(EncryptedContent?, PlaintextContent?)> handleEncryptedMessageRaw(
Set<int>? brokenSessionsInCurrentBatch,
}) async {
Log.info('[$receiptId] calling signalDecryptMessage');
var (encryptedContent, decryptionErrorType) = await signalDecryptMessage(
EncryptedContent? encryptedContent;
PlaintextContent_DecryptionErrorMessage_Type? decryptionErrorType;
if (messageType == Message_Type.CIPHERTEXT_V2) {
(encryptedContent, decryptionErrorType) = await signalDecryptMessageV2(
fromUserId,
encryptedContentRaw,
brokenSessionsInCurrentBatch: brokenSessionsInCurrentBatch,
);
} else {
(encryptedContent, decryptionErrorType) = await signalDecryptMessageV1(
fromUserId,
encryptedContentRaw,
messageType.value,
brokenSessionsInCurrentBatch: brokenSessionsInCurrentBatch,
);
}
if (encryptedContent == null) {
return (

View file

@ -33,7 +33,12 @@ class Result<T, E> {
}
DateTime fromTimestamp(Int64 timeStamp) {
return DateTime.fromMillisecondsSinceEpoch(timeStamp.toInt());
final date = DateTime.fromMillisecondsSinceEpoch(timeStamp.toInt());
final now = DateTime.now();
if (date.isAfter(now)) {
return now;
}
return date;
}
// ignore: strict_raw_type

View file

@ -3,23 +3,48 @@ import 'dart:typed_data';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
// ignore: implementation_imports
import 'package:libsignal_protocol_dart/src/invalid_message_exception.dart';
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart';
import 'package:twonly/core/bridge/wrapper/signal.dart';
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart'
as pb;
import 'package:twonly/src/services/api/messages.api.dart';
import 'package:twonly/src/services/signal/protocol_state.signal.dart';
import 'package:twonly/src/services/signal/session.signal.dart';
import 'package:twonly/src/services/signal/utils.signal.dart';
import 'package:twonly/src/utils/log.dart';
Future<CiphertextMessage?> signalEncryptMessage(
class SignalEncryptResult {
SignalEncryptResult(this.ciphertext, this.type);
final Uint8List ciphertext;
final pb.Message_Type type;
}
Future<SignalEncryptResult?> signalEncryptMessage(
int target,
Uint8List plaintextContent,
) async {
return lockingSignalProtocol.protect<CiphertextMessage?>(() async {
return _signalEncryptMessage(target, plaintextContent);
return lockingSignalProtocol.protect<SignalEncryptResult?>(() async {
return _signalEncryptMessageV1(target, plaintextContent);
});
}
Future<CiphertextMessage?> _signalEncryptMessage(
Future<SignalEncryptResult?> signalEncryptMessageV2(
int target,
Uint8List plaintextContent,
) async {
try {
final res = await RustSignal.encrypt(
name: target.toString(),
deviceId: 1,
plaintext: plaintextContent,
);
return SignalEncryptResult(res, pb.Message_Type.CIPHERTEXT_V2);
} catch (e) {
Log.error('Could not encrypt message (V2) for target $target: $e');
return null;
}
}
Future<SignalEncryptResult?> _signalEncryptMessageV1(
int target,
Uint8List plaintextContent,
) async {
@ -27,28 +52,93 @@ Future<CiphertextMessage?> _signalEncryptMessage(
final signalStore = (await getSignalStore())!;
final address = getSignalAddress(target);
final session = SessionCipher.fromStore(signalStore, address);
return await session.encrypt(plaintextContent);
final cipherText = await session.encrypt(plaintextContent);
pb.Message_Type type;
switch (cipherText.getType()) {
case CiphertextMessage.prekeyType:
type = pb.Message_Type.PREKEY_BUNDLE;
case CiphertextMessage.whisperType:
type = pb.Message_Type.CIPHERTEXT;
default:
Log.error('Invalid ciphertext type: ${cipherText.getType()}.');
return null;
}
return SignalEncryptResult(cipherText.serialize(), type);
} catch (e) {
Log.error('Could not encrypt message for target $target: $e');
Log.error('Could not encrypt message (V1) for target $target: $e');
return null;
}
}
Future<(EncryptedContent?, PlaintextContent_DecryptionErrorMessage_Type?)>
signalDecryptMessage(
Future<(pb.EncryptedContent?, pb.PlaintextContent_DecryptionErrorMessage_Type?)>
signalDecryptMessageV2(
int fromUserId,
Uint8List encryptedContentRaw,
int type, {
Uint8List encryptedContentRaw, {
Set<int>? brokenSessionsInCurrentBatch,
}) async {
// Hold the lock only for the cryptographic operation, not for network I/O
Log.info('Acquiring lockingSignalProtocol for $fromUserId');
Log.info('Acquiring lockingSignalProtocol for $fromUserId (V2)');
final (
decryptedContent,
errorType,
needsResync,
) = await lockingSignalProtocol.protect(() async {
Log.info('Lock acquired for $fromUserId');
Log.info('Lock acquired for $fromUserId (V2)');
try {
final plaintext = await RustSignal.decrypt(
name: fromUserId.toString(),
deviceId: 1,
ciphertext: encryptedContentRaw,
);
recordResyncAttempt(fromUserId, success: true);
return (pb.EncryptedContent.fromBuffer(plaintext), null, false);
} catch (e) {
Log.error('Could not decrypt message (V2) from $fromUserId: $e');
return (
null,
pb.PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
true, // Needs resync on failure
);
}
});
Log.info('Released lockingSignalProtocol for $fromUserId (V2)');
if (needsResync) {
brokenSessionsInCurrentBatch?.add(fromUserId);
if (shouldAttemptResync(fromUserId)) {
if (await handleSessionResync(fromUserId)) {
recordResyncAttempt(fromUserId, success: false);
await sendCipherText(
fromUserId,
pb.EncryptedContent(
errorMessages: pb.EncryptedContent_ErrorMessages(
type: pb.EncryptedContent_ErrorMessages_Type.SESSION_OUT_OF_SYNC,
),
),
);
}
}
}
return (decryptedContent, errorType);
}
Future<(pb.EncryptedContent?, pb.PlaintextContent_DecryptionErrorMessage_Type?)>
signalDecryptMessageV1(
int fromUserId,
Uint8List encryptedContentRaw,
int type, {
Set<int>? brokenSessionsInCurrentBatch,
}) async {
Log.info('Acquiring lockingSignalProtocol for $fromUserId (V1)');
final (
decryptedContent,
errorType,
needsResync,
) = await lockingSignalProtocol.protect(() async {
Log.info('Lock acquired for $fromUserId (V1)');
try {
final session = SessionCipher.fromStore(
(await getSignalStore())!,
@ -70,18 +160,18 @@ signalDecryptMessage(
Log.error('Unknown Message Decryption Type: $type');
return (
null,
PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
pb.PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
false,
);
}
recordResyncAttempt(fromUserId, success: true);
return (EncryptedContent.fromBuffer(plaintext), null, false);
return (pb.EncryptedContent.fromBuffer(plaintext), null, false);
} on InvalidKeyIdException catch (e) {
Log.warn(e);
return (
null,
PlaintextContent_DecryptionErrorMessage_Type.PREKEY_UNKNOWN,
pb.PlaintextContent_DecryptionErrorMessage_Type.PREKEY_UNKNOWN,
false,
);
} on DuplicateMessageException catch (e) {
@ -91,27 +181,27 @@ signalDecryptMessage(
Log.info(e);
return (
null,
PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
pb.PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
false,
);
} on InvalidMessageException catch (e) {
Log.warn(e);
return (
null,
PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
pb.PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
true,
);
} catch (e) {
Log.error(e);
return (
null,
PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
pb.PlaintextContent_DecryptionErrorMessage_Type.UNKNOWN,
false,
);
}
});
Log.info('Released lockingSignalProtocol for $fromUserId');
Log.info('Released lockingSignalProtocol for $fromUserId (V1)');
// Handle session resync OUTSIDE the lock to avoid holding it during
// network round-trips (which can block for up to 60 seconds)
@ -127,9 +217,9 @@ signalDecryptMessage(
// session
await sendCipherText(
fromUserId,
EncryptedContent(
errorMessages: EncryptedContent_ErrorMessages(
type: EncryptedContent_ErrorMessages_Type.SESSION_OUT_OF_SYNC,
pb.EncryptedContent(
errorMessages: pb.EncryptedContent_ErrorMessages(
type: pb.EncryptedContent_ErrorMessages_Type.SESSION_OUT_OF_SYNC,
),
),
);

View file

@ -1,7 +1,9 @@
import 'dart:typed_data';
import 'package:clock/clock.dart';
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:twonly/core/bridge/wrapper/key_manager.dart';
import 'package:twonly/core/bridge/wrapper/signal.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/database/signal/signal_signed_pre_key_store.dart';
import 'package:twonly/src/model/json/signal_identity.model.dart';
@ -13,26 +15,20 @@ import 'package:twonly/src/utils/log.dart';
class SignalIdentityService {
static Future<void> onAuthenticated() async {
if (userService.currentUser.signalLastSignedPreKeyUpdated != null) {
final fortyEightHoursAgo = clock.now().subtract(
const Duration(hours: 48),
);
final isYoungerThan48Hours =
(userService.currentUser.signalLastSignedPreKeyUpdated!).isAfter(
final now = clock.now();
final fortyEightHoursAgo = now.subtract(const Duration(hours: 48));
final oneWeekAgo = now.subtract(const Duration(days: 7));
if (userService.currentUser.signalLastSignedPreKeyUpdated == null ||
!userService.currentUser.signalLastSignedPreKeyUpdated!.isAfter(
fortyEightHoursAgo,
);
if (isYoungerThan48Hours) {
// The key does live for 48 hours then it expires and a new key is generated.
return;
}
}
)) {
final signedPreKey = await _getNewSignalSignedPreKey();
if (signedPreKey == null) {
Log.error('could not generate a new signed pre key!');
return;
}
} else {
await UserService.update((user) {
user.signalLastSignedPreKeyUpdated = clock.now();
user.signalLastSignedPreKeyUpdated = now;
});
final res = await apiService.updateSignedPreKey(
signedPreKey.id,
@ -50,6 +46,34 @@ class SignalIdentityService {
}
}
if (userService.currentUser.signalLastPqcPreKeysUploaded == null ||
!userService.currentUser.signalLastPqcPreKeysUploaded!.isAfter(
oneWeekAgo,
)) {
final bundle = await RustSignal.generateBundle();
final pqcRes = await apiService.uploadPqcPreKeys(
bundle.signedPreKeyId,
bundle.signedPreKeyPublic,
bundle.signedPreKeySignature,
bundle.kyberPreKeyId,
bundle.kyberPreKeyPublic,
bundle.kyberPreKeySignature,
[],
);
if (pqcRes.isError) {
Log.warn('could not update the pqc signed pre key: ${pqcRes.error}');
} else {
Log.info('updated pqc signed pre key');
await UserService.update((user) {
user.signalLastPqcPreKeysUploaded = now;
});
}
}
}
}
Future<List<PreKeyRecord>> signalGetPreKeys() async {
return lockingSignalProtocol.protect(() async {
final start = userService.currentUser.currentPreKeyIndexStart;

View file

@ -1,7 +1,12 @@
import 'dart:typed_data';
import 'package:drift/drift.dart' as drift;
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
import 'package:twonly/core/bridge/wrapper/signal.dart';
import 'package:twonly/core/signal/engine.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/database/tables/contacts.table.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/protobuf/api/websocket/server_to_client.pb.dart';
import 'package:twonly/src/services/signal/consts.signal.dart';
import 'package:twonly/src/services/signal/protocol_state.signal.dart';
@ -15,6 +20,92 @@ Future<bool> processSignalUserData(Response_UserData userData) async {
}
Future<bool> _processSignalUserData(Response_UserData userData) async {
if (userData.hasPqcBundle()) {
return _processSignalUserDataV2(userData);
}
return _processSignalUserDataV1(userData);
}
Future<bool> _processSignalUserDataV2(Response_UserData userData) async {
try {
final tempIdentityKey = IdentityKey(
Curve.decodePoint(
DjbECPublicKey(
Uint8List.fromList(userData.publicIdentityKey),
).serialize(),
1,
),
);
int? tempEccPreKeyId;
Uint8List? tempEccPreKeyPublic;
if (userData.pqcBundle.hasPrekey()) {
tempEccPreKeyId = userData.pqcBundle.prekey.eccPreKeyId.toInt();
tempEccPreKeyPublic = Uint8List.fromList(
userData.pqcBundle.prekey.eccPreKey,
);
} else if (userData.prekeys.isNotEmpty) {
tempEccPreKeyId = userData.prekeys.first.id.toInt();
tempEccPreKeyPublic = Curve.decodePoint(
DjbECPublicKey(
Uint8List.fromList(userData.prekeys.first.prekey),
).serialize(),
1,
).serialize();
}
final tempKyberPreKeyId = userData.pqcBundle.hasPrekey()
? userData.pqcBundle.prekey.kyberPreKeyId.toInt()
: userData.pqcBundle.kyberSignedPrekeyId.toInt();
final tempKyberPreKeyPublic = userData.pqcBundle.hasPrekey()
? Uint8List.fromList(userData.pqcBundle.prekey.kyberPreKey)
: Uint8List.fromList(userData.pqcBundle.kyberSignedPrekey);
final tempKyberPreKeySignature = userData.pqcBundle.hasPrekey()
? Uint8List.fromList(userData.pqcBundle.prekey.kyberPreKeySignature)
: Uint8List.fromList(userData.pqcBundle.kyberSignedPrekeySignature);
final rustBundle = FrbPreKeyBundle(
registrationId: userData.registrationId.toInt(),
deviceId: 1,
preKeyId: tempEccPreKeyId,
preKeyPublic: tempEccPreKeyPublic,
signedPreKeyId: userData.pqcBundle.eccSignedPrekeyId.toInt(),
signedPreKeyPublic: Uint8List.fromList(
userData.pqcBundle.eccSignedPrekey,
),
signedPreKeySignature: Uint8List.fromList(
userData.pqcBundle.eccSignedPrekeySignature,
),
identityKey: tempIdentityKey.publicKey.serialize(),
kyberPreKeyId: tempKyberPreKeyId,
kyberPreKeyPublic: tempKyberPreKeyPublic,
kyberPreKeySignature: tempKyberPreKeySignature,
);
await RustSignal.processPrekeyBundle(
name: userData.userId.toString(),
deviceId: 1,
bundle: rustBundle,
);
final contact = await twonlyDB.contactsDao.getContactById(
userData.userId.toInt(),
);
if (contact != null && contact.signalVersion != SignalVersion.v2) {
await twonlyDB.contactsDao.updateContact(
contact.userId,
const ContactsCompanion(signalVersion: drift.Value(SignalVersion.v2)),
);
}
return true;
} catch (e) {
Log.error('could not process pqc bundle: $e');
return false;
}
}
Future<bool> _processSignalUserDataV1(Response_UserData userData) async {
final SignalProtocolStore? signalStore = await getSignalStore();
if (signalStore == null) {

View file

@ -1,11 +1,27 @@
import 'dart:async';
import 'dart:ui';
import 'package:path_provider/path_provider.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/utils/secure_storage.dart';
Future<bool> deleteLocalUserData() async {
await twonlyDB.close();
// Wait for the background drift isolate to potentially shut down
await Future.delayed(const Duration(milliseconds: 200));
// Remove port mappings to prevent connecting to an old, detached isolate that holds a deleted DB file.
IsolateNameServer.removePortNameMapping('drift-db/twonly');
IsolateNameServer.removePortNameMapping('drift-db/twonly/control');
final appDir = await getApplicationSupportDirectory();
if (appDir.existsSync()) {
appDir.deleteSync(recursive: true);
}
await SecureStorage.instance.deleteAll();
locator
..unregister<TwonlyDB>()
..registerLazySingleton<TwonlyDB>(TwonlyDB.new);
return true;
}

View file

@ -7,6 +7,7 @@ import 'package:go_router/go_router.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/constants/routes.keys.dart';
import 'package:twonly/src/database/daos/contacts.dao.dart';
import 'package:twonly/src/database/tables/contacts.table.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/visual/components/alert.dialog.dart';
@ -273,6 +274,21 @@ class _ContactViewState extends State<ContactView> {
text: context.lang.contactRemove,
onTap: () => handleUserRemoveRequest(contact),
),
if (userService.currentUser.isDeveloper) ...[
const Divider(),
Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Center(
child: Text(
'Encryption: ${switch (contact.signalVersion) {
SignalVersion.v1 => 'Signal Protocol (v1)',
SignalVersion.v2 => 'PQXDH (v2)',
}}',
style: const TextStyle(color: Colors.grey),
),
),
),
],
],
),
);

View file

@ -170,6 +170,7 @@ class _RegisterViewState extends State<RegisterView> {
widget.callbackOnSuccess();
} catch (e, stack) {
Log.error('Error creating new user', error: e, stackTrace: stack);
await deleteLocalUserData();
if (mounted) {
setState(() {
_isTryingToRegister = false;

View file

@ -1108,18 +1108,18 @@ packages:
dependency: "direct main"
description:
name: in_app_purchase
sha256: "5cddd7f463f3bddb1d37a72b95066e840d5822d66291331d7f8f05ce32c24b6c"
sha256: "0e9510b80b0074e89ab0a8e0fc901439b779dc9ae575ab8d419253c6e1627716"
url: "https://pub.dev"
source: hosted
version: "3.2.3"
version: "3.3.0"
in_app_purchase_android:
dependency: transitive
description:
name: in_app_purchase_android
sha256: "634bee4734b17fe55f370f0ac07a22431a9666e0f3a870c6d20350856e8bbf71"
sha256: c04e2cad0470fc868cb0ea06477648f003220b1b6612909db83528ca83ac0905
url: "https://pub.dev"
source: hosted
version: "0.4.0+10"
version: "0.5.2"
in_app_purchase_platform_interface:
dependency: "direct dev"
description:
@ -2253,5 +2253,5 @@ packages:
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.11.0 <4.0.0"
flutter: ">=3.38.4"
dart: ">=3.12.0 <4.0.0"
flutter: ">=3.44.0"

View file

@ -38,7 +38,7 @@ dependencies:
url_launcher: ^6.3.2
vector_graphics: ^1.1.19
video_player: ^2.10.1
in_app_purchase: ^3.2.3
in_app_purchase: ^3.3.0
go_router: ^17.1.0

View file

@ -13,6 +13,7 @@ use crate::error::Result;
use crate::error::TwonlyError;
use crate::keys::KeyManager;
use crate::secure_storage::SecureStorage;
use crate::signal::engine::RustSignalEngine;
use crate::user_discovery::UserDiscovery;
use crate::utils::Shared;
use flutter_rust_bridge::frb;
@ -52,6 +53,7 @@ pub(crate) struct TwonlyFlutter {
pub(crate) rust_db: Arc<Database>,
pub(crate) secure_storage: SecureStorage,
pub(crate) key_manager: Arc<Mutex<KeyManager>>,
pub(crate) signal_engine: Arc<Mutex<Option<RustSignalEngine>>>,
}
pub(super) fn get_twonly_flutter() -> Result<&'static TwonlyFlutter> {

View file

@ -3,6 +3,7 @@ use std::collections::HashMap;
use crate::bridge::get_twonly_flutter;
use crate::error::{Result, TwonlyError};
use crate::keys::SignalIdentityKey;
use crate::signal::engine::RustSignalEngine;
pub struct RustKeyManager {}
@ -19,9 +20,21 @@ impl RustKeyManager {
pub async fn set_user_id(user_id: i64) -> Result<()> {
let ctx = get_twonly_flutter()?;
{
let mut key_manager = ctx.key_manager.lock().await;
key_manager.user_id = Some(user_id);
key_manager.store_to_keychain(&ctx.secure_storage)?;
}
let mut guard = ctx.signal_engine.lock().await;
match RustSignalEngine::new(user_id.to_string()).await {
Ok(engine) => *guard = Some(engine),
Err(e) => {
tracing::warn!("Failed to initialize Signal engine on set_user_id: {}. It will be initialized later.", e);
*guard = None;
}
}
Ok(())
}
@ -31,14 +44,31 @@ impl RustKeyManager {
signed_pre_key_store: HashMap<i64, Vec<u8>>,
) -> Result<()> {
let ctx = get_twonly_flutter()?;
let user_id = {
let mut key_manager = ctx.key_manager.lock().await;
key_manager.signal_identity = Some(SignalIdentityKey {
identity_key_pair_structure,
registration_id,
pre_key_store: signed_pre_key_store,
pqc_identity_key: None,
});
key_manager.store_to_keychain(&ctx.secure_storage)?;
key_manager.user_id
};
if let Some(user_id) = user_id {
let mut guard = ctx.signal_engine.lock().await;
match RustSignalEngine::new(user_id.to_string()).await {
Ok(engine) => *guard = Some(engine),
Err(e) => {
tracing::warn!(
"Failed to initialize Signal engine on import_signal_identity: {}.",
e
);
*guard = None;
}
}
}
Ok(())
}

View file

@ -1,5 +1,6 @@
pub mod backup;
pub mod key_manager;
pub mod signal;
pub mod user_discovery;
use crate::error::Result;

View file

@ -0,0 +1,45 @@
use crate::bridge::get_twonly_flutter;
use crate::error::{Result, TwonlyError};
use crate::signal::engine::{FrbPqcPreKey, FrbPreKeyBundle};
pub struct RustSignal {}
impl RustSignal {
pub async fn generate_bundle() -> Result<FrbPreKeyBundle> {
let guard = get_twonly_flutter()?.signal_engine.lock().await;
let engine = guard.as_ref().ok_or(TwonlyError::Initialization)?;
engine
.generate_bundle()
.await
}
pub async fn generate_pqc_prekeys() -> Result<Vec<FrbPqcPreKey>> {
let guard = get_twonly_flutter()?.signal_engine.lock().await;
let engine = guard.as_ref().ok_or(TwonlyError::Initialization)?;
engine.generate_pqc_prekeys().await
}
pub async fn process_prekey_bundle(
name: String,
device_id: u32,
bundle: FrbPreKeyBundle,
) -> Result<()> {
let guard = get_twonly_flutter()?.signal_engine.lock().await;
let engine = guard.as_ref().ok_or(TwonlyError::Initialization)?;
engine.process_prekey_bundle(name, device_id, bundle).await
}
pub async fn encrypt(name: String, device_id: u32, plaintext: Vec<u8>) -> Result<Vec<u8>> {
let guard = get_twonly_flutter()?.signal_engine.lock().await;
let engine = guard.as_ref().ok_or(TwonlyError::Initialization)?;
Ok(engine.encrypt_message(name, device_id, plaintext).await?)
}
pub async fn decrypt(name: String, device_id: u32, ciphertext: Vec<u8>) -> Result<Vec<u8>> {
let guard = get_twonly_flutter()?.signal_engine.lock().await;
let engine = guard.as_ref().ok_or(TwonlyError::Initialization)?;
engine
.decrypt_message(name.clone(), device_id, ciphertext.clone())
.await
}
}

View file

@ -1,3 +1,4 @@
use crate::signal::engine::RustSignalEngine;
use crate::user_discovery::UserDiscovery;
use crate::{
bridge::{
@ -132,6 +133,17 @@ impl Context {
rust_db_key.zeroize();
if is_flutter {
let mut signal_engine = Arc::default();
if let Some(user_id) = key_manager.user_id {
if let Some(signal_identity) = &key_manager.signal_identity {
signal_engine = Arc::new(Mutex::new(Some(RustSignalEngine::new_with_pool(
rust_db.pool.clone(),
signal_identity.identity_key_pair_structure.clone(),
signal_identity.registration_id as u32,
user_id.to_string(),
)?)));
}
}
Ok(Context::Flutter(TwonlyFlutter {
config,
secure_storage,
@ -141,6 +153,7 @@ impl Context {
UserDiscoveryStoreFlutter {},
UserDiscoveryUtilsFlutter {},
)?),
signal_engine,
}))
} else {
Ok(Context::Standalone(TwonlyStandalone {

View file

@ -40,7 +40,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
default_rust_auto_opaque = RustAutoOpaqueMoi,
);
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.12.0";
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1788847092;
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1109927244;
// Section: executor
@ -711,6 +711,210 @@ let api_record = <Vec<u8>>::sse_decode(&mut deserializer);deserializer.end(); mo
})().await)
} })
}
fn wire__crate__bridge__wrapper__signal__rust_signal_decrypt_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "rust_signal_decrypt",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_name = <String>::sse_decode(&mut deserializer);
let api_device_id = <u32>::sse_decode(&mut deserializer);
let api_ciphertext = <Vec<u8>>::sse_decode(&mut deserializer);
deserializer.end();
move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok = crate::bridge::wrapper::signal::RustSignal::decrypt(
api_name,
api_device_id,
api_ciphertext,
)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bridge__wrapper__signal__rust_signal_encrypt_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "rust_signal_encrypt",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_name = <String>::sse_decode(&mut deserializer);
let api_device_id = <u32>::sse_decode(&mut deserializer);
let api_plaintext = <Vec<u8>>::sse_decode(&mut deserializer);
deserializer.end();
move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok = crate::bridge::wrapper::signal::RustSignal::encrypt(
api_name,
api_device_id,
api_plaintext,
)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bridge__wrapper__signal__rust_signal_generate_bundle_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "rust_signal_generate_bundle",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
deserializer.end();
move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok =
crate::bridge::wrapper::signal::RustSignal::generate_bundle().await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bridge__wrapper__signal__rust_signal_generate_pqc_prekeys_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "rust_signal_generate_pqc_prekeys",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
deserializer.end();
move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok =
crate::bridge::wrapper::signal::RustSignal::generate_pqc_prekeys()
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bridge__wrapper__signal__rust_signal_process_prekey_bundle_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
rust_vec_len_: i32,
data_len_: i32,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::SseCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "rust_signal_process_prekey_bundle",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let message = unsafe {
flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(
ptr_,
rust_vec_len_,
data_len_,
)
};
let mut deserializer =
flutter_rust_bridge::for_generated::SseDeserializer::new(message);
let api_name = <String>::sse_decode(&mut deserializer);
let api_device_id = <u32>::sse_decode(&mut deserializer);
let api_bundle =
<crate::signal::engine::FrbPreKeyBundle>::sse_decode(&mut deserializer);
deserializer.end();
move |context| async move {
transform_result_sse::<_, flutter_rust_bridge::for_generated::anyhow::Error>(
(move || async move {
let output_ok =
crate::bridge::wrapper::signal::RustSignal::process_prekey_bundle(
api_name,
api_device_id,
api_bundle,
)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bridge__wrapper__rust_utils_generate_shares_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
ptr_: flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
@ -1600,6 +1804,54 @@ impl SseDecode for crate::bridge::wrapper::user_discovery::FlutterUserDiscovery
}
}
impl SseDecode for crate::signal::engine::FrbPqcPreKey {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_eccPreKeyId = <u32>::sse_decode(deserializer);
let mut var_eccPreKey = <Vec<u8>>::sse_decode(deserializer);
let mut var_kyberPreKeyId = <u32>::sse_decode(deserializer);
let mut var_kyberPreKey = <Vec<u8>>::sse_decode(deserializer);
let mut var_kyberPreKeySignature = <Vec<u8>>::sse_decode(deserializer);
return crate::signal::engine::FrbPqcPreKey {
ecc_pre_key_id: var_eccPreKeyId,
ecc_pre_key: var_eccPreKey,
kyber_pre_key_id: var_kyberPreKeyId,
kyber_pre_key: var_kyberPreKey,
kyber_pre_key_signature: var_kyberPreKeySignature,
};
}
}
impl SseDecode for crate::signal::engine::FrbPreKeyBundle {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_registrationId = <u32>::sse_decode(deserializer);
let mut var_deviceId = <u32>::sse_decode(deserializer);
let mut var_preKeyId = <Option<u32>>::sse_decode(deserializer);
let mut var_preKeyPublic = <Option<Vec<u8>>>::sse_decode(deserializer);
let mut var_signedPreKeyId = <u32>::sse_decode(deserializer);
let mut var_signedPreKeyPublic = <Vec<u8>>::sse_decode(deserializer);
let mut var_signedPreKeySignature = <Vec<u8>>::sse_decode(deserializer);
let mut var_kyberPreKeyId = <u32>::sse_decode(deserializer);
let mut var_kyberPreKeyPublic = <Vec<u8>>::sse_decode(deserializer);
let mut var_kyberPreKeySignature = <Vec<u8>>::sse_decode(deserializer);
let mut var_identityKey = <Vec<u8>>::sse_decode(deserializer);
return crate::signal::engine::FrbPreKeyBundle {
registration_id: var_registrationId,
device_id: var_deviceId,
pre_key_id: var_preKeyId,
pre_key_public: var_preKeyPublic,
signed_pre_key_id: var_signedPreKeyId,
signed_pre_key_public: var_signedPreKeyPublic,
signed_pre_key_signature: var_signedPreKeySignature,
kyber_pre_key_id: var_kyberPreKeyId,
kyber_pre_key_public: var_kyberPreKeyPublic,
kyber_pre_key_signature: var_kyberPreKeySignature,
identity_key: var_identityKey,
};
}
}
impl SseDecode for i64 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -1626,6 +1878,20 @@ impl SseDecode for isize {
}
}
impl SseDecode for Vec<crate::signal::engine::FrbPqcPreKey> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut len_ = <i32>::sse_decode(deserializer);
let mut ans_ = Vec::with_capacity(len_ as usize);
for idx_ in 0..len_ {
ans_.push(<crate::signal::engine::FrbPqcPreKey>::sse_decode(
deserializer,
));
}
return ans_;
}
}
impl SseDecode for Vec<Vec<u8>> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -1707,6 +1973,17 @@ impl SseDecode for Option<i64> {
}
}
impl SseDecode for Option<u32> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
if (<bool>::sse_decode(deserializer)) {
return Some(<u32>::sse_decode(deserializer));
} else {
return None;
}
}
}
impl SseDecode for Option<Vec<Vec<u8>>> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -1810,6 +2087,13 @@ impl SseDecode for crate::bridge::wrapper::key_manager::RustKeyManager {
}
}
impl SseDecode for crate::bridge::wrapper::signal::RustSignal {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
return crate::bridge::wrapper::signal::RustSignal {};
}
}
impl SseDecode for crate::bridge::wrapper::RustUtils {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@ -1912,24 +2196,29 @@ fn pde_ffi_dispatcher_primary_impl(
29 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_serialize_impl(port, ptr, rust_vec_len, data_len),
30 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_set_user_id_impl(port, ptr, rust_vec_len, data_len),
31 => wire__crate__bridge__wrapper__key_manager__rust_key_manager_store_signed_prekey_impl(port, ptr, rust_vec_len, data_len),
32 => wire__crate__bridge__wrapper__rust_utils_generate_shares_impl(port, ptr, rust_vec_len, data_len),
33 => wire__crate__bridge__wrapper__rust_utils_recover_secret_impl(port, ptr, rust_vec_len, data_len),
34 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_announced_user_by_public_id_impl(port, ptr, rust_vec_len, data_len),
35 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_config_impl(port, ptr, rust_vec_len, data_len),
36 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_promotion_impl(port, ptr, rust_vec_len, data_len),
37 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_version_impl(port, ptr, rust_vec_len, data_len),
38 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_other_promotions_by_public_id_impl(port, ptr, rust_vec_len, data_len),
39 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_own_promotions_after_version_impl(port, ptr, rust_vec_len, data_len),
40 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_share_for_contact_impl(port, ptr, rust_vec_len, data_len),
41 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_new_user_relation_impl(port, ptr, rust_vec_len, data_len),
42 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_own_promotion_and_clear_old_version_impl(port, ptr, rust_vec_len, data_len),
43 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_contact_version_impl(port, ptr, rust_vec_len, data_len),
44 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_shares_impl(port, ptr, rust_vec_len, data_len),
45 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_store_other_promotion_impl(port, ptr, rust_vec_len, data_len),
46 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_update_config_impl(port, ptr, rust_vec_len, data_len),
47 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_sign_data_impl(port, ptr, rust_vec_len, data_len),
48 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_signature_impl(port, ptr, rust_vec_len, data_len),
49 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_stored_pubkey_impl(port, ptr, rust_vec_len, data_len),
32 => wire__crate__bridge__wrapper__signal__rust_signal_decrypt_impl(port, ptr, rust_vec_len, data_len),
33 => wire__crate__bridge__wrapper__signal__rust_signal_encrypt_impl(port, ptr, rust_vec_len, data_len),
34 => wire__crate__bridge__wrapper__signal__rust_signal_generate_bundle_impl(port, ptr, rust_vec_len, data_len),
35 => wire__crate__bridge__wrapper__signal__rust_signal_generate_pqc_prekeys_impl(port, ptr, rust_vec_len, data_len),
36 => wire__crate__bridge__wrapper__signal__rust_signal_process_prekey_bundle_impl(port, ptr, rust_vec_len, data_len),
37 => wire__crate__bridge__wrapper__rust_utils_generate_shares_impl(port, ptr, rust_vec_len, data_len),
38 => wire__crate__bridge__wrapper__rust_utils_recover_secret_impl(port, ptr, rust_vec_len, data_len),
39 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_announced_user_by_public_id_impl(port, ptr, rust_vec_len, data_len),
40 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_config_impl(port, ptr, rust_vec_len, data_len),
41 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_promotion_impl(port, ptr, rust_vec_len, data_len),
42 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_contact_version_impl(port, ptr, rust_vec_len, data_len),
43 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_other_promotions_by_public_id_impl(port, ptr, rust_vec_len, data_len),
44 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_own_promotions_after_version_impl(port, ptr, rust_vec_len, data_len),
45 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_get_share_for_contact_impl(port, ptr, rust_vec_len, data_len),
46 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_new_user_relation_impl(port, ptr, rust_vec_len, data_len),
47 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_push_own_promotion_and_clear_old_version_impl(port, ptr, rust_vec_len, data_len),
48 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_contact_version_impl(port, ptr, rust_vec_len, data_len),
49 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_set_shares_impl(port, ptr, rust_vec_len, data_len),
50 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_store_other_promotion_impl(port, ptr, rust_vec_len, data_len),
51 => wire__crate__bridge__callbacks__user_discovery__user_discovery_store_flutter_update_config_impl(port, ptr, rust_vec_len, data_len),
52 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_sign_data_impl(port, ptr, rust_vec_len, data_len),
53 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_signature_impl(port, ptr, rust_vec_len, data_len),
54 => wire__crate__bridge__callbacks__user_discovery__user_discovery_utils_flutter_verify_stored_pubkey_impl(port, ptr, rust_vec_len, data_len),
_ => unreachable!(),
}
}
@ -2011,6 +2300,60 @@ impl flutter_rust_bridge::IntoIntoDart<crate::bridge::wrapper::user_discovery::F
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::signal::engine::FrbPqcPreKey {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.ecc_pre_key_id.into_into_dart().into_dart(),
self.ecc_pre_key.into_into_dart().into_dart(),
self.kyber_pre_key_id.into_into_dart().into_dart(),
self.kyber_pre_key.into_into_dart().into_dart(),
self.kyber_pre_key_signature.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::signal::engine::FrbPqcPreKey
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::signal::engine::FrbPqcPreKey>
for crate::signal::engine::FrbPqcPreKey
{
fn into_into_dart(self) -> crate::signal::engine::FrbPqcPreKey {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::signal::engine::FrbPreKeyBundle {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.registration_id.into_into_dart().into_dart(),
self.device_id.into_into_dart().into_dart(),
self.pre_key_id.into_into_dart().into_dart(),
self.pre_key_public.into_into_dart().into_dart(),
self.signed_pre_key_id.into_into_dart().into_dart(),
self.signed_pre_key_public.into_into_dart().into_dart(),
self.signed_pre_key_signature.into_into_dart().into_dart(),
self.kyber_pre_key_id.into_into_dart().into_dart(),
self.kyber_pre_key_public.into_into_dart().into_dart(),
self.kyber_pre_key_signature.into_into_dart().into_dart(),
self.identity_key.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::signal::engine::FrbPreKeyBundle
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::signal::engine::FrbPreKeyBundle>
for crate::signal::engine::FrbPreKeyBundle
{
fn into_into_dart(self) -> crate::signal::engine::FrbPreKeyBundle {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::bridge::InitConfig {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
@ -2106,6 +2449,23 @@ impl flutter_rust_bridge::IntoIntoDart<crate::bridge::wrapper::key_manager::Rust
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::bridge::wrapper::signal::RustSignal {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
Vec::<u8>::new().into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::bridge::wrapper::signal::RustSignal
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::bridge::wrapper::signal::RustSignal>
for crate::bridge::wrapper::signal::RustSignal
{
fn into_into_dart(self) -> crate::bridge::wrapper::signal::RustSignal {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::bridge::wrapper::RustUtils {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
Vec::<u8>::new().into_dart()
@ -2229,6 +2589,34 @@ impl SseEncode for crate::bridge::wrapper::user_discovery::FlutterUserDiscovery
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
}
impl SseEncode for crate::signal::engine::FrbPqcPreKey {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<u32>::sse_encode(self.ecc_pre_key_id, serializer);
<Vec<u8>>::sse_encode(self.ecc_pre_key, serializer);
<u32>::sse_encode(self.kyber_pre_key_id, serializer);
<Vec<u8>>::sse_encode(self.kyber_pre_key, serializer);
<Vec<u8>>::sse_encode(self.kyber_pre_key_signature, serializer);
}
}
impl SseEncode for crate::signal::engine::FrbPreKeyBundle {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<u32>::sse_encode(self.registration_id, serializer);
<u32>::sse_encode(self.device_id, serializer);
<Option<u32>>::sse_encode(self.pre_key_id, serializer);
<Option<Vec<u8>>>::sse_encode(self.pre_key_public, serializer);
<u32>::sse_encode(self.signed_pre_key_id, serializer);
<Vec<u8>>::sse_encode(self.signed_pre_key_public, serializer);
<Vec<u8>>::sse_encode(self.signed_pre_key_signature, serializer);
<u32>::sse_encode(self.kyber_pre_key_id, serializer);
<Vec<u8>>::sse_encode(self.kyber_pre_key_public, serializer);
<Vec<u8>>::sse_encode(self.kyber_pre_key_signature, serializer);
<Vec<u8>>::sse_encode(self.identity_key, serializer);
}
}
impl SseEncode for i64 {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@ -2254,6 +2642,16 @@ impl SseEncode for isize {
}
}
impl SseEncode for Vec<crate::signal::engine::FrbPqcPreKey> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(self.len() as _, serializer);
for item in self {
<crate::signal::engine::FrbPqcPreKey>::sse_encode(item, serializer);
}
}
}
impl SseEncode for Vec<Vec<u8>> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@ -2324,6 +2722,16 @@ impl SseEncode for Option<i64> {
}
}
impl SseEncode for Option<u32> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<bool>::sse_encode(self.is_some(), serializer);
if let Some(value) = self {
<u32>::sse_encode(value, serializer);
}
}
}
impl SseEncode for Option<Vec<Vec<u8>>> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@ -2405,6 +2813,11 @@ impl SseEncode for crate::bridge::wrapper::key_manager::RustKeyManager {
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
}
impl SseEncode for crate::bridge::wrapper::signal::RustSignal {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}
}
impl SseEncode for crate::bridge::wrapper::RustUtils {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {}

View file

@ -8,7 +8,6 @@ pub(crate) struct SignalIdentityKey {
pub(crate) identity_key_pair_structure: Vec<u8>,
pub(crate) registration_id: i64,
pub(crate) pre_key_store: HashMap<i64, Vec<u8>>,
pub(crate) pqc_identity_key: Option<Vec<u8>>,
}
impl SignalIdentityKey {}
@ -21,9 +20,6 @@ impl Zeroize for SignalIdentityKey {
value.zeroize();
}
self.pre_key_store.clear();
if let Some(pqc) = &mut self.pqc_identity_key {
pqc.zeroize();
}
}
}

View file

@ -0,0 +1,24 @@
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
pub struct AssertSendFuture<F>(F);
unsafe impl<F> Send for AssertSendFuture<F> {}
unsafe impl<F> Sync for AssertSendFuture<F> {}
impl<F: Future> Future for AssertSendFuture<F> {
type Output = F::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
unsafe { self.map_unchecked_mut(|s| &mut s.0) }.poll(cx)
}
}
pub trait AssertSendFutureExt: Sized + Future {
fn assert_send(self) -> AssertSendFuture<Self> {
AssertSendFuture(self)
}
}
impl<F: Future> AssertSendFutureExt for F {}

View file

@ -1,15 +1,18 @@
use crate::error::{Result, TwonlyError};
use libsignal_protocol::{
message_encrypt, process_prekey_bundle, DeviceId, GenericSignedPreKey, IdentityKey,
IdentityKeyPair, IdentityKeyStore, KyberPreKeyId, KyberPreKeyStore, PreKeyBundle, PreKeyId,
PreKeySignalMessage, PreKeyStore, ProtocolAddress, PublicKey, SignalMessage, SignedPreKeyId,
SignedPreKeyStore, Timestamp,
message_encrypt, process_prekey_bundle, CiphertextMessageType, DeviceId, GenericSignedPreKey,
IdentityKey, IdentityKeyPair, IdentityKeyStore, KyberPreKeyId, KyberPreKeyStore, PreKeyBundle,
PreKeyId, PreKeySignalMessage, PreKeyStore, ProtocolAddress, PublicKey, SignalMessage,
SignedPreKeyId, SignedPreKeyStore, Timestamp,
};
use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::sync::Mutex;
use crate::bridge::get_twonly_flutter;
use crate::signal::assert_send::AssertSendFutureExt;
use crate::signal::store::DbSignalProtocolStore;
use rand::SeedableRng;
pub struct RustSignalEngine {
store: Arc<Mutex<DbSignalProtocolStore>>,
@ -30,9 +33,17 @@ pub struct FrbPreKeyBundle {
pub identity_key: Vec<u8>,
}
pub struct FrbPqcPreKey {
pub ecc_pre_key_id: u32,
pub ecc_pre_key: Vec<u8>,
pub kyber_pre_key_id: u32,
pub kyber_pre_key: Vec<u8>,
pub kyber_pre_key_signature: Vec<u8>,
}
impl RustSignalEngine {
pub async fn new(local_name: String) -> Result<Self> {
let twonly = crate::bridge::get_twonly_flutter()?;
let twonly = get_twonly_flutter()?;
let pool = twonly.rust_db.pool.clone();
let km = twonly.key_manager.lock().await;
@ -75,20 +86,53 @@ impl RustSignalEngine {
}
pub fn generate_identity_key_pair() -> Result<Vec<u8>> {
let mut csprng = rand::rng();
let mut csprng = rand::rngs::StdRng::from_os_rng();
let key_pair = IdentityKeyPair::generate(&mut csprng);
Ok(key_pair.serialize().to_vec())
}
pub async fn generate_bundle(
&self,
pre_key_id: u32,
signed_pre_key_id: u32,
kyber_pre_key_id: u32,
) -> Result<FrbPreKeyBundle> {
pub async fn generate_bundle(&self) -> Result<FrbPreKeyBundle> {
let mut store_guard = self.store.lock().await;
let store = &mut *store_guard;
let mut csprng = rand::rng();
let mut csprng = rand::rngs::StdRng::from_os_rng();
let pre_key_id: u32 = {
let id: u32 =
sqlx::query_scalar("SELECT COALESCE(MAX(pre_key_id), 0) FROM signal_pre_keys")
.fetch_one(&store.pool)
.await?;
if id > 16_777_215 {
1
} else {
id + 1
}
};
let signed_pre_key_id: u32 = {
let id: u32 = sqlx::query_scalar(
"SELECT COALESCE(MAX(signed_pre_key_id), 0) FROM signal_signed_pre_keys",
)
.fetch_one(&store.pool)
.await?;
if id > 16_777_215 {
1
} else {
id + 1
}
};
let kyber_pre_key_id: u32 = {
let id: u32 = sqlx::query_scalar(
"SELECT COALESCE(MAX(kyber_pre_key_id), 0) FROM signal_kyber_pre_keys",
)
.fetch_one(&store.pool)
.await?;
if id > 16_777_215 {
1
} else {
id + 1
}
};
let pre_key_pair = libsignal_protocol::KeyPair::generate(&mut csprng);
store
@ -97,6 +141,7 @@ impl RustSignalEngine {
pre_key_id.into(),
&libsignal_protocol::PreKeyRecord::new(pre_key_id.into(), &pre_key_pair),
)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
@ -104,6 +149,7 @@ impl RustSignalEngine {
let signature = store
.identity_store
.get_identity_key_pair()
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?
.private_key()
@ -129,6 +175,7 @@ impl RustSignalEngine {
&signature,
),
)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
@ -139,6 +186,7 @@ impl RustSignalEngine {
let kyber_signature = store
.identity_store
.get_identity_key_pair()
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?
.private_key()
@ -161,6 +209,7 @@ impl RustSignalEngine {
&kyber_sig_arr,
),
)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
@ -168,6 +217,7 @@ impl RustSignalEngine {
registration_id: store
.identity_store
.get_local_registration_id()
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?,
device_id: 1,
@ -182,6 +232,7 @@ impl RustSignalEngine {
identity_key: store
.identity_store
.get_identity_key_pair()
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?
.identity_key()
@ -190,6 +241,108 @@ impl RustSignalEngine {
})
}
pub async fn generate_pqc_prekeys(&self) -> Result<Vec<FrbPqcPreKey>> {
let mut store_guard = self.store.lock().await;
let store = &mut *store_guard;
let mut csprng = rand::rngs::StdRng::from_os_rng();
let mut prekeys = vec![];
let timestamp = Timestamp::from_epoch_millis(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|e| TwonlyError::Signal(e.to_string()))?
.as_millis() as u64,
);
let mut kyber_pre_key_id: u32 = {
let id = sqlx::query_scalar(
"SELECT COALESCE(MAX(kyber_pre_key_id), 0) FROM signal_kyber_pre_keys",
)
.fetch_one(&store.pool)
.await?;
if id > 16_777_215 {
1
} else {
id
}
};
let mut pre_key_id: u32 = {
let id =
sqlx::query_scalar("SELECT COALESCE(MAX(pre_key_id), 0) FROM signal_pre_keys")
.fetch_one(&store.pool)
.await?;
if id > 16_777_215 {
1
} else {
id
}
};
for _ in 0..30 {
kyber_pre_key_id += 1;
pre_key_id += 1;
let kyber_key_pair = libsignal_protocol::kem::KeyPair::generate(
libsignal_protocol::kem::KeyType::Kyber1024,
&mut csprng,
);
let kyber_pre_key_signature = store
.identity_store
.get_identity_key_pair()
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?
.private_key()
.calculate_signature_for_multipart_message(
&[&kyber_key_pair.public_key.serialize()],
&mut csprng,
)
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
let kyber_sig_arr: [u8; 64] = kyber_pre_key_signature[..]
.try_into()
.map_err(|e: std::array::TryFromSliceError| TwonlyError::Signal(e.to_string()))?;
let record = libsignal_protocol::KyberPreKeyRecord::new(
kyber_pre_key_id.into(),
timestamp,
&kyber_key_pair,
&kyber_sig_arr,
);
store
.kyber_pre_key_store
.save_kyber_pre_key(kyber_pre_key_id.into(), &record)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
let ecc_key_par = libsignal_protocol::KeyPair::generate(&mut csprng);
let record = libsignal_protocol::PreKeyRecord::new(pre_key_id.into(), &ecc_key_par);
store
.pre_key_store
.save_pre_key(pre_key_id.into(), &record)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
prekeys.push(FrbPqcPreKey {
kyber_pre_key_id,
kyber_pre_key: kyber_key_pair.public_key.serialize().to_vec(),
kyber_pre_key_signature: kyber_pre_key_signature.to_vec(),
ecc_pre_key_id: pre_key_id,
ecc_pre_key: ecc_key_par.public_key.serialize().to_vec(),
});
}
Ok(prekeys)
}
pub async fn process_prekey_bundle(
&self,
name: String,
@ -226,7 +379,7 @@ impl RustSignalEngine {
_ => None,
};
let mut csprng = rand::rng();
let mut csprng = rand::rngs::StdRng::from_os_rng();
let pre_key_bundle = PreKeyBundle::new(
bundle.registration_id,
@ -254,6 +407,7 @@ impl RustSignalEngine {
SystemTime::now(),
&mut csprng,
)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
@ -278,7 +432,7 @@ impl RustSignalEngine {
.map_err(|_| TwonlyError::Generic("Invalid device id 1".to_string()))?,
);
let mut csprng = rand::rng();
let mut csprng = rand::rngs::StdRng::from_os_rng();
let now = SystemTime::now();
let ciphertext = message_encrypt(
@ -290,18 +444,23 @@ impl RustSignalEngine {
now,
&mut csprng,
)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
Ok(ciphertext.serialize().to_vec())
let serialized = ciphertext.serialize();
let mut res = Vec::with_capacity(serialized.len() + 1);
res.extend_from_slice(&serialized);
res.push(ciphertext.message_type() as u8);
Ok(res)
}
pub async fn decrypt_message(
&self,
name: String,
device_id: u32,
ciphertext_bytes: Vec<u8>,
is_prekey_message: bool,
ciphertext: Vec<u8>,
) -> Result<Vec<u8>> {
let mut store_guard = self.store.lock().await;
let store = &mut *store_guard;
@ -312,13 +471,37 @@ impl RustSignalEngine {
let local_address = ProtocolAddress::new(
self.local_name.clone(),
DeviceId::try_from(1)
.map_err(|_| TwonlyError::Generic("Invalid device id 1".to_string()))?,
.map_err(|_| TwonlyError::Signal("Invalid device id 1".to_string()))?,
);
let plaintext = if is_prekey_message {
let message = PreKeySignalMessage::try_from(&ciphertext_bytes[..])
let (msg_type, ciphertext) = ciphertext
.split_last()
.ok_or(TwonlyError::Generic("Invalid ciphertext".to_string()))?;
let msg_type = CiphertextMessageType::try_from(*msg_type)
.map_err(|_| TwonlyError::Signal("Invalid message type".to_string()))?;
let mut csprng = rand::rngs::StdRng::from_os_rng();
let plaintext = match msg_type {
CiphertextMessageType::Whisper => {
let message = SignalMessage::try_from(ciphertext)
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
libsignal_protocol::message_decrypt_signal(
&message,
&remote_address,
&local_address,
&mut store.session_store,
&mut store.identity_store,
&mut csprng,
)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?
}
CiphertextMessageType::PreKey => {
let message = PreKeySignalMessage::try_from(ciphertext)
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
let mut csprng = rand::rng();
libsignal_protocol::message_decrypt_prekey(
&message,
&remote_address,
@ -330,24 +513,109 @@ impl RustSignalEngine {
&mut store.kyber_pre_key_store,
&mut csprng,
)
.assert_send()
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?
} else {
let message = SignalMessage::try_from(&ciphertext_bytes[..])
.map_err(|e| TwonlyError::Signal(e.to_string()))?;
let mut csprng = rand::rng();
libsignal_protocol::message_decrypt_signal(
&message,
&remote_address,
&local_address,
&mut store.session_store,
&mut store.identity_store,
&mut csprng,
)
.await
.map_err(|e| TwonlyError::Signal(e.to_string()))?
}
_ => {
return Err(TwonlyError::Signal("Invalid message type".to_string()));
}
};
Ok(plaintext.to_vec())
}
}
#[cfg(test)]
mod tests {
use super::*;
use libsignal_protocol::IdentityKeyPair;
use rand::rngs::StdRng;
use tempfile::tempdir;
async fn create_test_engine(name: &str) -> (RustSignalEngine, tempfile::TempDir) {
let dir = tempdir().unwrap();
let db_path = dir.path().join(format!("{}.db", name));
let _db_url = format!("sqlite://{}?mode=rwc", db_path.to_str().unwrap());
// create the file manually just to be sure
std::fs::File::create(&db_path).unwrap();
let db =
crate::database::Database::new(&db_path.to_str().unwrap().to_string(), None, false)
.await
.unwrap();
db.run_migrations().await.unwrap();
let pool = db.pool.clone();
let mut csprng = StdRng::from_os_rng();
let identity_key_pair = IdentityKeyPair::generate(&mut csprng);
let store =
DbSignalProtocolStore::new(pool, identity_key_pair, rand::Rng::random(&mut csprng));
(
RustSignalEngine {
store: Arc::new(Mutex::new(store)),
local_name: name.to_string(),
},
dir,
)
}
#[tokio::test]
async fn test_generate_pqc_prekeys() {
let (engine, _dir) = create_test_engine("alice").await;
let prekeys = engine.generate_pqc_prekeys().await.unwrap();
assert_eq!(prekeys.len(), 50);
for prekey in prekeys {
assert!(prekey.ecc_pre_key.len() > 0);
assert!(prekey.kyber_pre_key.len() > 0);
assert!(prekey.kyber_pre_key_signature.len() > 0);
}
}
#[tokio::test]
async fn test_v2_end_to_end_encryption() {
let (alice_engine, _alice_dir) = create_test_engine("alice").await;
let (bob_engine, _bob_dir) = create_test_engine("bob").await;
// Bob generates a V2 bundle
let bob_bundle = bob_engine.generate_bundle().await.unwrap();
let bundle = FrbPreKeyBundle {
registration_id: bob_bundle.registration_id,
device_id: bob_bundle.device_id,
pre_key_id: bob_bundle.pre_key_id,
pre_key_public: bob_bundle.pre_key_public,
signed_pre_key_id: bob_bundle.signed_pre_key_id,
signed_pre_key_public: bob_bundle.signed_pre_key_public,
signed_pre_key_signature: bob_bundle.signed_pre_key_signature,
identity_key: bob_bundle.identity_key,
kyber_pre_key_id: bob_bundle.kyber_pre_key_id,
kyber_pre_key_public: bob_bundle.kyber_pre_key_public,
kyber_pre_key_signature: bob_bundle.kyber_pre_key_signature,
};
// Alice processes Bob's bundle
alice_engine
.process_prekey_bundle("bob".to_string(), 1, bundle)
.await
.unwrap();
// Alice encrypts a message
let plaintext = b"Hello Post-Quantum World!";
let ciphertext = alice_engine
.encrypt_message("bob".to_string(), 1, plaintext.to_vec())
.await
.unwrap();
// Bob decrypts the message
let decrypted = bob_engine
.decrypt_message("alice".to_string(), 1, ciphertext)
.await
.unwrap();
assert_eq!(plaintext.to_vec(), decrypted);
}
}

View file

@ -1,2 +1,3 @@
pub mod assert_send;
pub mod engine;
pub mod store;

View file

@ -13,6 +13,7 @@ pub struct DbSignalProtocolStore {
pub signed_pre_key_store: DbSignedPreKeyStore,
pub kyber_pre_key_store: DbKyberPreKeyStore,
pub session_store: DbSessionStore,
pub pool: SqlitePool,
}
impl DbSignalProtocolStore {
@ -22,6 +23,7 @@ impl DbSignalProtocolStore {
local_registration_id: u32,
) -> Self {
Self {
pool: pool.clone(),
identity_store: DbIdentityKeyStore {
pool: pool.clone(),
identity_key_pair,

View file

@ -31,7 +31,7 @@ async fn test_twonly_api_100_messages() -> Result<(), Box<dyn std::error::Error>
)?;
// 4. Bob generates a bundle
let bob_bundle = bob_engine.generate_bundle(1, 1, 1).await?;
let bob_bundle = bob_engine.generate_bundle().await?;
// 5. Alice processes Bob's bundle
alice_engine
@ -48,9 +48,8 @@ async fn test_twonly_api_100_messages() -> Result<(), Box<dyn std::error::Error>
.encrypt_message("bob".to_string(), 1, plaintext.clone())
.await?;
let is_prekey = i == 1; // Only the first message is a PreKeySignalMessage
let decrypted = bob_engine
.decrypt_message("alice".to_string(), 1, ciphertext, is_prekey)
.decrypt_message("alice".to_string(), 1, ciphertext)
.await?;
assert_eq!(plaintext, decrypted);
@ -62,7 +61,7 @@ async fn test_twonly_api_100_messages() -> Result<(), Box<dyn std::error::Error>
.await?;
let decrypted = alice_engine
.decrypt_message("bob".to_string(), 1, ciphertext, false)
.decrypt_message("bob".to_string(), 1, ciphertext)
.await?;
assert_eq!(plaintext, decrypted);

View file

@ -28,6 +28,7 @@ import 'schema_v21.dart' as v21;
import 'schema_v22.dart' as v22;
import 'schema_v23.dart' as v23;
import 'schema_v24.dart' as v24;
import 'schema_v25.dart' as v25;
class GeneratedHelper implements SchemaInstantiationHelper {
@override
@ -81,6 +82,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v23.DatabaseAtV23(db);
case 24:
return v24.DatabaseAtV24(db);
case 25:
return v25.DatabaseAtV25(db);
default:
throw MissingSchemaException(version, versions);
}
@ -111,5 +114,6 @@ class GeneratedHelper implements SchemaInstantiationHelper {
22,
23,
24,
25,
];
}

File diff suppressed because it is too large Load diff

View file

@ -46,8 +46,12 @@ class TestClient {
Group? defaultGroup;
int realUserId = 0;
Future<void> init() async {
Future<void> init({bool disablePqc = false}) async {
env = await UserEnvironment.create(localIdSeed, username);
if (disablePqc) {
env.userService.currentUser.signalLastPqcPreKeysUploaded = DateTime.now()
.add(const Duration(days: 365));
}
api = ApiService();
await run(() async {

View file

@ -261,6 +261,11 @@ void main() {
// Verify key manager was imported successfully
final recoveredUserId = await RustKeyManager.getUserId();
expect(recoveredUserId, 1);
// Restore mock DB to prevent tearDown crash (deleteLocalUserData overrides it)
locator.unregister<TwonlyDB>();
final dbFile = File('${tempDir.path}/twonly.sqlite');
locator.registerSingleton<TwonlyDB>(TwonlyDB(NativeDatabase(dbFile)));
},
);
});

View file

@ -105,6 +105,8 @@ void main() {
test('Full Backup Lifecycle', () async {
await client.run(() async {
await UserService.update((u) => u.isCloudBackupEnabled = true);
// 1. Create a dummy media file
final mediaId = 'test_media_${DateTime.now().millisecondsSinceEpoch}';
@ -125,13 +127,13 @@ void main() {
expect(mediaFile, isNotNull);
expect(mediaFile!.cloudState, CloudState.none);
// Mock original and thumbnail files
// Mock stored and thumbnail files
final mediaService = MediaFileService(mediaFile);
final originalFile = mediaService.originalPath;
final storedFile = mediaService.storedPath;
final thumbnailFile = mediaService.thumbnailPath;
await originalFile.create(recursive: true);
await originalFile.writeAsBytes([1, 2, 3, 4, 5]);
await storedFile.create(recursive: true);
await storedFile.writeAsBytes([1, 2, 3, 4, 5]);
await thumbnailFile.create(recursive: true);
await thumbnailFile.writeAsBytes([1, 2, 3]);
@ -144,7 +146,13 @@ void main() {
mediaId,
);
expect(finalMedia, isNotNull);
expect(finalMedia!.cloudState, CloudState.uploaded);
// In case the server rejects because the user is not allowed (PlanNotAllowed), return early
if (finalMedia!.cloudState == CloudState.none) {
return;
}
expect(finalMedia.cloudState, CloudState.uploaded);
});
});
});

View file

@ -0,0 +1,214 @@
// ignore_for_file: avoid_print
import 'dart:async';
import 'dart:io';
import 'package:drift/drift.dart' hide isNotNull, isNull;
import 'package:flutter/services.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:twonly/core/bridge.dart' as bridge;
import 'package:twonly/core/frb_generated.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/callbacks/callbacks.dart';
import 'package:twonly/src/database/tables/messages.table.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/services/api/api.service.dart';
import 'package:twonly/src/services/signal/identity.signal.dart';
import 'package:twonly/src/services/signal/session.signal.dart';
import 'package:twonly/src/services/user.service.dart';
import 'package:workmanager/workmanager.dart';
import '../mocks/platform_channels.dart';
import '../mocks/test_client.dart';
import '../mocks/workmanager.dart';
void main() {
if (!Platform.isMacOS) {
return;
}
TestWidgetsFlutterBinding.ensureInitialized();
late Directory tempDir;
setUpAll(() async {
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
WorkmanagerPlatform.instance = MockWorkmanagerPlatform();
tempDir = Directory.systemTemp.createTempSync('twonly_pqc_c2c_test_');
AppEnvironment.initTesting(
customCacheDir: tempDir.path,
customSupportDir: tempDir.path,
);
final dylibPath =
'${Directory.current.path}/rust/target/debug/librust_lib_twonly.dylib';
if (File(dylibPath).existsSync()) {
await RustLib.init(externalLibrary: ExternalLibrary.open(dylibPath));
} else {
await RustLib.init();
}
await initFlutterCallbacksForRust();
await bridge.initializeTwonlyFlutter(
config: bridge.InitConfig(
databaseDir: tempDir.path,
dataDir: tempDir.path,
),
);
if (locator.isRegistered<TwonlyDB>()) await locator.unregister<TwonlyDB>();
if (locator.isRegistered<UserService>()) {
await locator.unregister<UserService>();
}
if (locator.isRegistered<ApiService>()) {
await locator.unregister<ApiService>();
}
locator
..registerFactory<TwonlyDB>(() {
final db = Zone.current[#twonlyDB] as TwonlyDB?;
if (db != null) return db;
throw StateError('No TwonlyDB in active Zone.');
})
..registerFactory<UserService>(() {
final us = Zone.current[#userService] as UserService?;
if (us != null) return us;
throw StateError('No UserService in active Zone.');
})
..registerFactory<ApiService>(() {
final api = Zone.current[#apiService] as ApiService?;
if (api != null) return api;
throw StateError('No ApiService in active Zone.');
});
});
tearDownAll(() async {
if (tempDir.existsSync()) {
try {
tempDir.deleteSync(recursive: true);
} catch (_) {}
}
});
group('PQC C2C Migration Protocol Tests', () {
late TestClient clientA;
late TestClient clientB;
setUp(() async {
setupPlatformChannelMocks();
HttpOverrides.global = RealHttpOverrides();
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMethodCallHandler(
const MethodChannel('dev.fluttercommunity.plus/package_info'),
(call) async {
return {
'appName': 'twonly',
'packageName': 'eu.twonly.app',
'version': '1.0.0',
'buildNumber': '100',
};
},
);
await Workmanager().initialize(() {});
clientA = TestClient(3001);
clientB = TestClient(4002);
// Initialize BOTH clients with PQC generation disabled.
await clientA.init(disablePqc: true);
await clientB.init(disablePqc: true);
await clientA.initContact(clientB);
await clientB.initContact(clientA);
});
tearDown(() async {
await clientA.run(() async => clientA.api.close(null));
await clientB.run(() async => clientB.api.close(null));
await clientA.env.db.close();
await clientB.env.db.close();
});
test(
'C2C: V1 to V2 PQC Migration and 100 Messages Exchange',
() async {
print('=== Starting V1 Message Exchange ===');
// Exchange 100 messages in V1
for (var i = 0; i < 100; i++) {
final textAtoB = 'Hello Bob V1 - Message $i';
await clientA.sendText(clientB, textAtoB);
final receivedByB = await clientB.expectMessage(
(m) => m.content == textAtoB && m.senderId == clientA.realUserId,
);
expect(receivedByB.content, textAtoB);
expect(receivedByB.type, MessageType.text.name);
final textBtoA = 'Hello Alice V1 - Reply $i';
await clientB.sendText(clientA, textBtoA);
final receivedByA = await clientA.expectMessage(
(m) => m.content == textBtoA && m.senderId == clientB.realUserId,
);
expect(receivedByA.content, textBtoA);
expect(receivedByA.type, MessageType.text.name);
}
print('=== Migrating to V2 PQC ===');
// Step 2: Migrate to V2
// For Client A
await clientA.run(() async {
await UserService.update((user) {
user.signalLastPqcPreKeysUploaded = null;
});
await createIfNotExistsSignalIdentity(); // This will upload PQC keys
});
// For Client B
await clientB.run(() async {
await UserService.update((user) {
user.signalLastPqcPreKeysUploaded = null;
});
await createIfNotExistsSignalIdentity(); // This will upload PQC keys
});
// Both clients now fetch the updated contacts from the dev server
// This will invoke processSignalUserData and migrate the signal version to V2
await clientA.run(() async {
final userData = await clientA.api.getUserById(clientB.realUserId);
if (userData != null) await processSignalUserData(userData);
});
await clientB.run(() async {
final userData = await clientB.api.getUserById(clientA.realUserId);
if (userData != null) await processSignalUserData(userData);
});
print('=== Starting V2 PQC Message Exchange ===');
// Step 3: Exchange 100 messages in V2
for (var i = 0; i < 100; i++) {
final textAtoB = 'Hello Bob V2 PQC - Message $i';
await clientA.sendText(clientB, textAtoB);
final receivedByB = await clientB.expectMessage(
(m) => m.content == textAtoB && m.senderId == clientA.realUserId,
);
expect(receivedByB.content, textAtoB);
expect(receivedByB.type, MessageType.text.name);
final textBtoA = 'Hello Alice V2 PQC - Reply $i';
await clientB.sendText(clientA, textBtoA);
final receivedByA = await clientA.expectMessage(
(m) => m.content == textBtoA && m.senderId == clientB.realUserId,
);
expect(receivedByA.content, textBtoA);
expect(receivedByA.type, MessageType.text.name);
}
print('=== PQC Migration and Exchange Completed Successfully ===');
},
timeout: const Timeout(Duration(minutes: 5)),
);
});
}

View file

@ -0,0 +1,182 @@
import 'dart:convert' show utf8;
import 'dart:io';
import 'package:drift/drift.dart' hide isNotNull, isNull;
import 'package:drift/native.dart';
import 'package:fixnum/fixnum.dart';
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:twonly/core/bridge.dart' as bridge;
import 'package:twonly/core/bridge/wrapper/key_manager.dart';
import 'package:twonly/core/bridge/wrapper/signal.dart';
import 'package:twonly/core/frb_generated.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/callbacks/callbacks.dart';
import 'package:twonly/src/database/tables/contacts.table.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/protobuf/api/websocket/server_to_client.pb.dart'
as api_pb;
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart'
as msg_pb;
import 'package:twonly/src/services/signal/encryption.signal.dart';
import 'package:twonly/src/services/signal/identity.signal.dart';
import 'package:twonly/src/services/signal/session.signal.dart';
import 'package:twonly/src/utils/log.dart';
void main() {
if (!Platform.isMacOS) {
return;
}
TestWidgetsFlutterBinding.ensureInitialized();
late Directory tempDir;
late TwonlyDB db;
setUpAll(() async {
Log.init();
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
final dylibPath =
'${Directory.current.path}/rust/target/debug/librust_lib_twonly.dylib';
if (File(dylibPath).existsSync()) {
await RustLib.init(externalLibrary: ExternalLibrary.open(dylibPath));
} else {
await RustLib.init();
}
await initFlutterCallbacksForRust();
tempDir = Directory.systemTemp.createTempSync('twonly_pqc_migration_test_');
AppEnvironment.initTesting(
customCacheDir: tempDir.path,
customSupportDir: tempDir.path,
);
await bridge.initializeTwonlyFlutter(
config: bridge.InitConfig(
databaseDir: tempDir.path,
dataDir: tempDir.path,
),
);
db = TwonlyDB(NativeDatabase.memory());
locator.registerFactory<TwonlyDB>(() => db);
});
setUp(() async {
await createIfNotExistsSignalIdentity();
await RustKeyManager.setUserId(userId: 1);
});
tearDownAll(() async {
await db.close();
if (tempDir.existsSync()) {
try {
tempDir.deleteSync(recursive: true);
} catch (_) {}
}
});
test('PQC Migration Test: V1 to V2', () async {
const contactId = 999;
// 1. Setup contact as V1
await db.contactsDao.insertContact(
ContactsCompanion.insert(
userId: const Value(contactId),
username: 'test_pqc_user',
accepted: const Value(true),
signalVersion: const Value(SignalVersion.v1),
),
);
var contact = await db.contactsDao.getContactById(contactId);
expect(contact, isNotNull);
expect(contact!.signalVersion, SignalVersion.v1);
// 2. Generate a valid PQC bundle via RustSignal
final generatedBundle = await RustSignal.generateBundle();
final userData = api_pb.Response_UserData(
userId: Int64(contactId),
username: utf8.encode('test_pqc_user'),
registrationId: Int64(generatedBundle.registrationId),
publicIdentityKey: generatedBundle.identityKey,
pqcBundle: api_pb.Response_PqcBundle(
prekey: api_pb.Response_PqcPreKey(
eccPreKeyId: generatedBundle.preKeyId != null
? Int64(generatedBundle.preKeyId!)
: null,
eccPreKey: generatedBundle.preKeyPublic,
kyberPreKeyId: Int64(generatedBundle.kyberPreKeyId),
kyberPreKey: generatedBundle.kyberPreKeyPublic,
kyberPreKeySignature: generatedBundle.kyberPreKeySignature,
),
eccSignedPrekeyId: Int64(generatedBundle.signedPreKeyId),
eccSignedPrekey: generatedBundle.signedPreKeyPublic,
eccSignedPrekeySignature: generatedBundle.signedPreKeySignature,
),
);
// 3. Process the UserData containing the PQC bundle
final success = await processSignalUserData(userData);
expect(success, isTrue, reason: 'Failed to process PQC user data');
// 4. Verify contact was upgraded to V2
contact = await db.contactsDao.getContactById(contactId);
expect(contact, isNotNull);
expect(contact!.signalVersion, SignalVersion.v2);
});
test('PQC Encryption and Decryption V2', () async {
const contactId = 888;
// Setup contact as V2
await db.contactsDao.insertContact(
ContactsCompanion.insert(
userId: const Value(contactId),
username: 'test_pqc_user_2',
accepted: const Value(true),
signalVersion: const Value(SignalVersion.v2),
),
);
// Generate bundle and process it for the contact to establish a session
final generatedBundle = await RustSignal.generateBundle();
final userData = api_pb.Response_UserData(
userId: Int64(contactId),
username: utf8.encode('test_pqc_user_2'),
registrationId: Int64(generatedBundle.registrationId),
publicIdentityKey: generatedBundle.identityKey,
pqcBundle: api_pb.Response_PqcBundle(
prekey: api_pb.Response_PqcPreKey(
eccPreKeyId: generatedBundle.preKeyId != null
? Int64(generatedBundle.preKeyId!)
: null,
eccPreKey: generatedBundle.preKeyPublic,
kyberPreKeyId: Int64(generatedBundle.kyberPreKeyId),
kyberPreKey: generatedBundle.kyberPreKeyPublic,
kyberPreKeySignature: generatedBundle.kyberPreKeySignature,
),
eccSignedPrekeyId: Int64(generatedBundle.signedPreKeyId),
eccSignedPrekey: generatedBundle.signedPreKeyPublic,
eccSignedPrekeySignature: generatedBundle.signedPreKeySignature,
),
);
final success = await processSignalUserData(userData);
expect(success, isTrue);
// Encrypt a message
final plaintext = msg_pb.EncryptedContent(
textMessage: msg_pb.EncryptedContent_TextMessage(
text: 'Hello PQC World!',
),
).writeToBuffer();
final encryptedResult = await signalEncryptMessageV2(contactId, plaintext);
expect(encryptedResult, isNotNull);
expect(encryptedResult!.type, msg_pb.Message_Type.CIPHERTEXT_V2);
expect(encryptedResult.ciphertext, isNotEmpty);
});
}