[mob] Simplify APIs for compress -> encrypt & vice versa (#2524)
## Description ## Tests
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
import "dart:async";
|
||||
import "dart:convert";
|
||||
import "dart:io";
|
||||
|
||||
import "package:computer/computer.dart";
|
||||
import "package:flutter/foundation.dart" show Uint8List;
|
||||
@@ -11,8 +9,8 @@ import "package:photos/models/file/file.dart";
|
||||
import 'package:photos/services/machine_learning/file_ml/file_ml.dart';
|
||||
import "package:photos/services/machine_learning/file_ml/files_ml_data_response.dart";
|
||||
import "package:photos/services/machine_learning/file_ml/remote_embedding.dart";
|
||||
import "package:photos/utils/crypto_util.dart";
|
||||
import "package:photos/utils/file_download_util.dart";
|
||||
import "package:photos/utils/gzip.dart";
|
||||
import "package:shared_preferences/shared_preferences.dart";
|
||||
|
||||
class RemoteFileMLService {
|
||||
@@ -36,22 +34,18 @@ class RemoteFileMLService {
|
||||
}) async {
|
||||
fileML.putClipIfNotNull(clipEmbedding);
|
||||
fileML.putFaceIfNotNull(faceEmbedding);
|
||||
final encryptionKey = getFileKey(file);
|
||||
final embeddingJSON = jsonEncode(fileML.remoteRawData);
|
||||
final compressedData = gzipUInt8List(utf8.encode(embeddingJSON));
|
||||
final encryptedEmbedding =
|
||||
await CryptoUtil.encryptChaCha(compressedData, encryptionKey);
|
||||
final encryptedData =
|
||||
CryptoUtil.bin2base64(encryptedEmbedding.encryptedData!);
|
||||
final header = CryptoUtil.bin2base64(encryptedEmbedding.header!);
|
||||
final ChaChaEncryptionResult encryptionResult = await gzipAndEncryptJson(
|
||||
fileML.remoteRawData,
|
||||
getFileKey(file),
|
||||
);
|
||||
try {
|
||||
final _ = await _dio.put(
|
||||
"/embeddings",
|
||||
data: {
|
||||
"fileID": file.uploadedFileID!,
|
||||
"model": 'ggml-clip',
|
||||
"encryptedEmbedding": encryptedData,
|
||||
"decryptionHeader": header,
|
||||
"encryptedEmbedding": encryptionResult.encData,
|
||||
"decryptionHeader": encryptionResult.header,
|
||||
},
|
||||
);
|
||||
} catch (e, s) {
|
||||
@@ -125,39 +119,21 @@ class RemoteFileMLService {
|
||||
}
|
||||
}
|
||||
|
||||
Uint8List ungzipUint8List(Uint8List compressedData) {
|
||||
final codec = GZipCodec();
|
||||
final List<int> decompressedList = codec.decode(compressedData);
|
||||
return Uint8List.fromList(decompressedList);
|
||||
}
|
||||
|
||||
// gzipUInt8List
|
||||
Uint8List gzipUInt8List(Uint8List data) {
|
||||
final codec = GZipCodec();
|
||||
final compressedData = codec.encode(data);
|
||||
return Uint8List.fromList(compressedData);
|
||||
}
|
||||
|
||||
Future<Map<int, RemoteFileML>> _decryptFileMLComputer(
|
||||
Map<String, dynamic> args,
|
||||
) async {
|
||||
final result = <int, RemoteFileML>{};
|
||||
final inputs = args["inputs"] as List<EmbeddingsDecoderInput>;
|
||||
for (final input in inputs) {
|
||||
final decryptArgs = <String, dynamic>{};
|
||||
decryptArgs["source"] =
|
||||
CryptoUtil.base642bin(input.embedding.encryptedEmbedding);
|
||||
decryptArgs["key"] = input.decryptionKey;
|
||||
decryptArgs["header"] =
|
||||
CryptoUtil.base642bin(input.embedding.decryptionHeader);
|
||||
final embeddingData = chachaDecryptData(decryptArgs);
|
||||
final unzippedData = ungzipUint8List(embeddingData);
|
||||
final decodedJson = jsonDecode(utf8.decode(unzippedData));
|
||||
final RemoteFileML decodedEmbedding = RemoteFileML.fromRemote(
|
||||
input.embedding.fileID,
|
||||
decodedJson as Map<String, dynamic>,
|
||||
final decodedJson = decryptAndUnzipJsonSync(
|
||||
input.decryptionKey,
|
||||
encryptedData: input.embedding.encryptedEmbedding,
|
||||
header: input.embedding.decryptionHeader,
|
||||
);
|
||||
result[input.embedding.fileID] = RemoteFileML.fromRemote(
|
||||
input.embedding.fileID,
|
||||
decodedJson,
|
||||
);
|
||||
result[input.embedding.fileID] = decodedEmbedding;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import "dart:convert";
|
||||
import "dart:io";
|
||||
|
||||
import "package:computer/computer.dart";
|
||||
import "package:flutter/foundation.dart";
|
||||
import "package:photos/utils/crypto_util.dart";
|
||||
|
||||
class ChaChaEncryptionResult {
|
||||
final String encData;
|
||||
final String header;
|
||||
|
||||
ChaChaEncryptionResult({
|
||||
required this.encData,
|
||||
required this.header,
|
||||
});
|
||||
}
|
||||
|
||||
Uint8List _unGzipUInt8List(Uint8List compressedData) {
|
||||
final codec = GZipCodec();
|
||||
final List<int> decompressedList = codec.decode(compressedData);
|
||||
return Uint8List.fromList(decompressedList);
|
||||
}
|
||||
|
||||
// gzipUInt8List
|
||||
Uint8List _gzipUInt8List(Uint8List data) {
|
||||
final codec = GZipCodec();
|
||||
final compressedData = codec.encode(data);
|
||||
return Uint8List.fromList(compressedData);
|
||||
}
|
||||
|
||||
Map<String, dynamic> decryptAndUnzipJsonSync(
|
||||
Uint8List key, {
|
||||
required String encryptedData,
|
||||
required String header,
|
||||
}) {
|
||||
final decryptedData = chachaDecryptData({
|
||||
"source": CryptoUtil.base642bin(encryptedData),
|
||||
"key": key,
|
||||
"header": CryptoUtil.base642bin(header),
|
||||
});
|
||||
final decompressedData = _unGzipUInt8List(decryptedData);
|
||||
final json = utf8.decode(decompressedData);
|
||||
return jsonDecode(json);
|
||||
}
|
||||
|
||||
// zipJsonAndEncryptSync performs all operations synchronously, on a single isolate.
|
||||
ChaChaEncryptionResult gzipAndEncryptJsonSync(
|
||||
Map<String, dynamic> jsonData,
|
||||
Uint8List key,
|
||||
) {
|
||||
final json = utf8.encode(jsonEncode(jsonData));
|
||||
final compressedJson = _gzipUInt8List(Uint8List.fromList(json));
|
||||
final encryptedData = chachaEncryptData({
|
||||
"source": compressedJson,
|
||||
"key": key,
|
||||
});
|
||||
return ChaChaEncryptionResult(
|
||||
encData: CryptoUtil.bin2base64(encryptedData.encryptedData!),
|
||||
header: CryptoUtil.bin2base64(encryptedData.header!),
|
||||
);
|
||||
}
|
||||
|
||||
Future<ChaChaEncryptionResult> gzipAndEncryptJson(
|
||||
Map<String, dynamic> jsonData,
|
||||
Uint8List key,
|
||||
) async {
|
||||
final Computer computer = Computer.shared();
|
||||
final response =
|
||||
await computer.compute<Map<String, dynamic>, ChaChaEncryptionResult>(
|
||||
_gzipAndEncryptJsonSync,
|
||||
param: {
|
||||
"jsonData": jsonData,
|
||||
"key": key,
|
||||
},
|
||||
taskName: "gzipAndEncryptJson",
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
ChaChaEncryptionResult _gzipAndEncryptJsonSync(
|
||||
Map<String, dynamic> args,
|
||||
) {
|
||||
return gzipAndEncryptJsonSync(args["jsonData"], args["key"]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user