فهرست منبع

Move all calls to Sodium to CryptoUtil

vishnukvmd 2 سال پیش
والد
کامیت
80f36d1bd5

+ 48 - 50
lib/core/configuration.dart

@@ -4,7 +4,6 @@ import 'dart:typed_data';
 
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:photos/core/constants.dart';
@@ -213,23 +212,23 @@ class Configuration {
         CryptoUtil.encryptSync(keyPair.sk, masterKey);
 
     final attributes = KeyAttributes(
-      Sodium.bin2base64(kekSalt),
-      Sodium.bin2base64(encryptedKeyData.encryptedData!),
-      Sodium.bin2base64(encryptedKeyData.nonce!),
-      Sodium.bin2base64(keyPair.pk),
-      Sodium.bin2base64(encryptedSecretKeyData.encryptedData!),
-      Sodium.bin2base64(encryptedSecretKeyData.nonce!),
+      CryptoUtil.bin2base64(kekSalt),
+      CryptoUtil.bin2base64(encryptedKeyData.encryptedData!),
+      CryptoUtil.bin2base64(encryptedKeyData.nonce!),
+      CryptoUtil.bin2base64(keyPair.pk),
+      CryptoUtil.bin2base64(encryptedSecretKeyData.encryptedData!),
+      CryptoUtil.bin2base64(encryptedSecretKeyData.nonce!),
       derivedKeyResult.memLimit,
       derivedKeyResult.opsLimit,
-      Sodium.bin2base64(encryptedMasterKey.encryptedData!),
-      Sodium.bin2base64(encryptedMasterKey.nonce!),
-      Sodium.bin2base64(encryptedRecoveryKey.encryptedData!),
-      Sodium.bin2base64(encryptedRecoveryKey.nonce!),
+      CryptoUtil.bin2base64(encryptedMasterKey.encryptedData!),
+      CryptoUtil.bin2base64(encryptedMasterKey.nonce!),
+      CryptoUtil.bin2base64(encryptedRecoveryKey.encryptedData!),
+      CryptoUtil.bin2base64(encryptedRecoveryKey.nonce!),
     );
     final privateAttributes = PrivateKeyAttributes(
-      Sodium.bin2base64(masterKey),
-      Sodium.bin2hex(recoveryKey),
-      Sodium.bin2base64(keyPair.sk),
+      CryptoUtil.bin2base64(masterKey),
+      CryptoUtil.bin2hex(recoveryKey),
+      CryptoUtil.bin2base64(keyPair.sk),
     );
     return KeyGenResult(attributes, privateAttributes);
   }
@@ -253,9 +252,9 @@ class Configuration {
     final existingAttributes = getKeyAttributes();
 
     return existingAttributes!.copyWith(
-      kekSalt: Sodium.bin2base64(kekSalt),
-      encryptedKey: Sodium.bin2base64(encryptedKeyData.encryptedData!),
-      keyDecryptionNonce: Sodium.bin2base64(encryptedKeyData.nonce!),
+      kekSalt: CryptoUtil.bin2base64(kekSalt),
+      encryptedKey: CryptoUtil.bin2base64(encryptedKeyData.encryptedData!),
+      keyDecryptionNonce: CryptoUtil.bin2base64(encryptedKeyData.nonce!),
       memLimit: derivedKeyResult.memLimit,
       opsLimit: derivedKeyResult.opsLimit,
     );
@@ -274,7 +273,7 @@ class Configuration {
     _logger.info('state validation done');
     final kek = await CryptoUtil.deriveKey(
       utf8.encode(password) as Uint8List,
-      Sodium.base642bin(attributes.kekSalt),
+      CryptoUtil.base642bin(attributes.kekSalt),
       attributes.memLimit!,
       attributes.opsLimit!,
     ).onError((e, s) {
@@ -286,31 +285,31 @@ class Configuration {
     Uint8List key;
     try {
       key = CryptoUtil.decryptSync(
-        Sodium.base642bin(attributes.encryptedKey),
+        CryptoUtil.base642bin(attributes.encryptedKey),
         kek,
-        Sodium.base642bin(attributes.keyDecryptionNonce),
+        CryptoUtil.base642bin(attributes.keyDecryptionNonce),
       );
     } catch (e) {
       _logger.severe('master-key failed, incorrect password?', e);
       throw Exception("Incorrect password");
     }
     _logger.info("master-key done");
-    await setKey(Sodium.bin2base64(key));
+    await setKey(CryptoUtil.bin2base64(key));
     final secretKey = CryptoUtil.decryptSync(
-      Sodium.base642bin(attributes.encryptedSecretKey),
+      CryptoUtil.base642bin(attributes.encryptedSecretKey),
       key,
-      Sodium.base642bin(attributes.secretKeyDecryptionNonce),
+      CryptoUtil.base642bin(attributes.secretKeyDecryptionNonce),
     );
     _logger.info("secret-key done");
-    await setSecretKey(Sodium.bin2base64(secretKey));
+    await setSecretKey(CryptoUtil.bin2base64(secretKey));
     final token = CryptoUtil.openSealSync(
-      Sodium.base642bin(getEncryptedToken()!),
-      Sodium.base642bin(attributes.publicKey),
+      CryptoUtil.base642bin(getEncryptedToken()!),
+      CryptoUtil.base642bin(attributes.publicKey),
       secretKey,
     );
     _logger.info('appToken done');
     await setToken(
-      Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe),
+      CryptoUtil.bin2base64(token, urlSafe: true),
     );
   }
 
@@ -319,7 +318,7 @@ class Configuration {
     _logger.info('state validation done');
     final kek = await CryptoUtil.deriveKey(
       utf8.encode(password) as Uint8List,
-      Sodium.base642bin(attributes.kekSalt),
+      CryptoUtil.base642bin(attributes.kekSalt),
       attributes.memLimit!,
       attributes.opsLimit!,
     ).onError((e, s) {
@@ -330,9 +329,9 @@ class Configuration {
     _logger.info('user-key done');
     try {
       final Uint8List key = CryptoUtil.decryptSync(
-        Sodium.base642bin(attributes.encryptedKey),
+        CryptoUtil.base642bin(attributes.encryptedKey),
         kek,
-        Sodium.base642bin(attributes.keyDecryptionNonce),
+        CryptoUtil.base642bin(attributes.keyDecryptionNonce),
       );
     } catch (e) {
       _logger.severe('master-key failed, incorrect password?', e);
@@ -353,12 +352,13 @@ class Configuration {
 
     return existingAttributes!.copyWith(
       masterKeyEncryptedWithRecoveryKey:
-          Sodium.bin2base64(encryptedMasterKey.encryptedData!),
-      masterKeyDecryptionNonce: Sodium.bin2base64(encryptedMasterKey.nonce!),
+          CryptoUtil.bin2base64(encryptedMasterKey.encryptedData!),
+      masterKeyDecryptionNonce:
+          CryptoUtil.bin2base64(encryptedMasterKey.nonce!),
       recoveryKeyEncryptedWithMasterKey:
-          Sodium.bin2base64(encryptedRecoveryKey.encryptedData!),
+          CryptoUtil.bin2base64(encryptedRecoveryKey.encryptedData!),
       recoveryKeyDecryptionNonce:
-          Sodium.bin2base64(encryptedRecoveryKey.nonce!),
+          CryptoUtil.bin2base64(encryptedRecoveryKey.nonce!),
     );
   }
 
@@ -376,29 +376,27 @@ class Configuration {
     Uint8List masterKey;
     try {
       masterKey = await CryptoUtil.decrypt(
-        Sodium.base642bin(attributes!.masterKeyEncryptedWithRecoveryKey!),
-        Sodium.hex2bin(recoveryKey),
-        Sodium.base642bin(attributes.masterKeyDecryptionNonce!),
+        CryptoUtil.base642bin(attributes!.masterKeyEncryptedWithRecoveryKey!),
+        CryptoUtil.hex2bin(recoveryKey),
+        CryptoUtil.base642bin(attributes.masterKeyDecryptionNonce!),
       );
     } catch (e) {
       _logger.severe(e);
       rethrow;
     }
-    await setKey(Sodium.bin2base64(masterKey));
+    await setKey(CryptoUtil.bin2base64(masterKey));
     final secretKey = CryptoUtil.decryptSync(
-      Sodium.base642bin(attributes.encryptedSecretKey),
+      CryptoUtil.base642bin(attributes.encryptedSecretKey),
       masterKey,
-      Sodium.base642bin(attributes.secretKeyDecryptionNonce),
+      CryptoUtil.base642bin(attributes.secretKeyDecryptionNonce),
     );
-    await setSecretKey(Sodium.bin2base64(secretKey));
+    await setSecretKey(CryptoUtil.bin2base64(secretKey));
     final token = CryptoUtil.openSealSync(
-      Sodium.base642bin(getEncryptedToken()!),
-      Sodium.base642bin(attributes.publicKey),
+      CryptoUtil.base642bin(getEncryptedToken()!),
+      CryptoUtil.base642bin(attributes.publicKey),
       secretKey,
     );
-    await setToken(
-      Sodium.bin2base64(token, variant: Sodium.base64VariantUrlsafe),
-    );
+    await setToken(CryptoUtil.bin2base64(token, urlSafe: true));
   }
 
   String getHttpEndpoint() {
@@ -506,19 +504,19 @@ class Configuration {
   }
 
   Uint8List? getKey() {
-    return _key == null ? null : Sodium.base642bin(_key!);
+    return _key == null ? null : CryptoUtil.base642bin(_key!);
   }
 
   Uint8List? getSecretKey() {
-    return _secretKey == null ? null : Sodium.base642bin(_secretKey!);
+    return _secretKey == null ? null : CryptoUtil.base642bin(_secretKey!);
   }
 
   Uint8List getRecoveryKey() {
     final keyAttributes = getKeyAttributes()!;
     return CryptoUtil.decryptSync(
-      Sodium.base642bin(keyAttributes.recoveryKeyEncryptedWithMasterKey!),
+      CryptoUtil.base642bin(keyAttributes.recoveryKeyEncryptedWithMasterKey!),
       getKey(),
-      Sodium.base642bin(keyAttributes.recoveryKeyDecryptionNonce!),
+      CryptoUtil.base642bin(keyAttributes.recoveryKeyDecryptionNonce!),
     );
   }
 

+ 37 - 38
lib/services/collections_service.dart

@@ -6,7 +6,6 @@ import 'dart:typed_data';
 import 'package:collection/collection.dart';
 import 'package:dio/dio.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/constants.dart';
@@ -310,7 +309,7 @@ class CollectionsService {
   ) async {
     final encryptedKey = CryptoUtil.sealSync(
       getCollectionKey(collectionID),
-      Sodium.base642bin(publicKey),
+      CryptoUtil.base642bin(publicKey),
     );
     try {
       final response = await _enteDio.post(
@@ -318,7 +317,7 @@ class CollectionsService {
         data: {
           "collectionID": collectionID,
           "email": email,
-          "encryptedKey": Sodium.bin2base64(encryptedKey),
+          "encryptedKey": CryptoUtil.bin2base64(encryptedKey),
           "role": role.toStringVal()
         },
       );
@@ -474,7 +473,7 @@ class CollectionsService {
       "Compute collection decryption key for ${collection.id} source"
       " $source",
     );
-    final encryptedKey = Sodium.base642bin(collection.encryptedKey);
+    final encryptedKey = CryptoUtil.base642bin(collection.encryptedKey);
     Uint8List? collectionKey;
     if (collection.owner?.id == _config.getUserID()) {
       if (_config.getKey() == null) {
@@ -483,12 +482,12 @@ class CollectionsService {
       collectionKey = CryptoUtil.decryptSync(
         encryptedKey,
         _config.getKey(),
-        Sodium.base642bin(collection.keyDecryptionNonce!),
+        CryptoUtil.base642bin(collection.keyDecryptionNonce!),
       );
     } else {
       collectionKey = CryptoUtil.openSealSync(
         encryptedKey,
-        Sodium.base642bin(_config.getKeyAttributes()!.publicKey),
+        CryptoUtil.base642bin(_config.getKeyAttributes()!.publicKey),
         _config.getSecretKey()!,
       );
     }
@@ -511,8 +510,8 @@ class CollectionsService {
         "/collections/rename",
         data: {
           "collectionID": collection.id,
-          "encryptedName": Sodium.bin2base64(encryptedName.encryptedData!),
-          "nameDecryptionNonce": Sodium.bin2base64(encryptedName.nonce!)
+          "encryptedName": CryptoUtil.bin2base64(encryptedName.encryptedData!),
+          "nameDecryptionNonce": CryptoUtil.bin2base64(encryptedName.nonce!)
         },
       );
       // trigger sync to fetch the latest name from server
@@ -570,8 +569,8 @@ class CollectionsService {
         magicMetadata: MetadataRequest(
           version: currentVersion,
           count: jsonToUpdate.length,
-          data: Sodium.bin2base64(encryptedMMd.encryptedData!),
-          header: Sodium.bin2base64(encryptedMMd.header!),
+          data: CryptoUtil.bin2base64(encryptedMMd.encryptedData!),
+          header: CryptoUtil.bin2base64(encryptedMMd.header!),
         ),
       );
       await _enteDio.put(
@@ -689,9 +688,9 @@ class CollectionsService {
           final decryptionKey =
               _getAndCacheDecryptedKey(collection, source: "fetchCollection");
           final utfEncodedMmd = await CryptoUtil.decryptChaCha(
-            Sodium.base642bin(collectionData['magicMetadata']['data']),
+            CryptoUtil.base642bin(collectionData['magicMetadata']['data']),
             decryptionKey,
-            Sodium.base642bin(collectionData['magicMetadata']['header']),
+            CryptoUtil.base642bin(collectionData['magicMetadata']['header']),
           );
           collection.mMdEncodedJson = utf8.decode(utfEncodedMmd);
           collection.mMdVersion = collectionData['magicMetadata']['version'];
@@ -721,10 +720,10 @@ class CollectionsService {
         CryptoUtil.encryptSync(utf8.encode(albumName) as Uint8List, key);
     final collection = await createAndCacheCollection(
       CreateRequest(
-        encryptedKey: Sodium.bin2base64(encryptedKeyData.encryptedData!),
-        keyDecryptionNonce: Sodium.bin2base64(encryptedKeyData.nonce!),
-        encryptedName: Sodium.bin2base64(encryptedName.encryptedData!),
-        nameDecryptionNonce: Sodium.bin2base64(encryptedName.nonce!),
+        encryptedKey: CryptoUtil.bin2base64(encryptedKeyData.encryptedData!),
+        keyDecryptionNonce: CryptoUtil.bin2base64(encryptedKeyData.nonce!),
+        encryptedName: CryptoUtil.bin2base64(encryptedName.encryptedData!),
+        nameDecryptionNonce: CryptoUtil.bin2base64(encryptedName.nonce!),
         type: CollectionType.album,
         attributes: CollectionAttributes(),
       ),
@@ -747,9 +746,9 @@ class CollectionsService {
           source: "fetchCollectionByID",
         );
         final utfEncodedMmd = await CryptoUtil.decryptChaCha(
-          Sodium.base642bin(collectionData['magicMetadata']['data']),
+          CryptoUtil.base642bin(collectionData['magicMetadata']['data']),
           decryptionKey,
-          Sodium.base642bin(collectionData['magicMetadata']['header']),
+          CryptoUtil.base642bin(collectionData['magicMetadata']['header']),
         );
         collection.mMdEncodedJson = utf8.decode(utfEncodedMmd);
         collection.mMdVersion = collectionData['magicMetadata']['version'];
@@ -784,14 +783,14 @@ class CollectionsService {
         CryptoUtil.encryptSync(utf8.encode(path) as Uint8List, key);
     final collection = await createAndCacheCollection(
       CreateRequest(
-        encryptedKey: Sodium.bin2base64(encryptedKeyData.encryptedData!),
-        keyDecryptionNonce: Sodium.bin2base64(encryptedKeyData.nonce!),
-        encryptedName: Sodium.bin2base64(encryptedPath.encryptedData!),
-        nameDecryptionNonce: Sodium.bin2base64(encryptedPath.nonce!),
+        encryptedKey: CryptoUtil.bin2base64(encryptedKeyData.encryptedData!),
+        keyDecryptionNonce: CryptoUtil.bin2base64(encryptedKeyData.nonce!),
+        encryptedName: CryptoUtil.bin2base64(encryptedPath.encryptedData!),
+        nameDecryptionNonce: CryptoUtil.bin2base64(encryptedPath.nonce!),
         type: CollectionType.folder,
         attributes: CollectionAttributes(
-          encryptedPath: Sodium.bin2base64(encryptedPath.encryptedData!),
-          pathDecryptionNonce: Sodium.bin2base64(encryptedPath.nonce!),
+          encryptedPath: CryptoUtil.bin2base64(encryptedPath.encryptedData!),
+          pathDecryptionNonce: CryptoUtil.bin2base64(encryptedPath.nonce!),
           version: 1,
         ),
       ),
@@ -830,8 +829,8 @@ class CollectionsService {
         file.collectionID = collectionID;
         final encryptedKeyData =
             CryptoUtil.encryptSync(key, getCollectionKey(collectionID));
-        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData!);
-        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce!);
+        file.encryptedKey = CryptoUtil.bin2base64(encryptedKeyData.encryptedData!);
+        file.keyDecryptionNonce = CryptoUtil.bin2base64(encryptedKeyData.nonce!);
         params["files"].add(
           CollectionFileItem(
             file.uploadedFileID!,
@@ -870,9 +869,9 @@ class CollectionsService {
         CryptoUtil.encryptSync(fileKey, getCollectionKey(destCollectionID));
 
     localFileToUpload.encryptedKey =
-        Sodium.bin2base64(encryptedKeyData.encryptedData!);
+        CryptoUtil.bin2base64(encryptedKeyData.encryptedData!);
     localFileToUpload.keyDecryptionNonce =
-        Sodium.bin2base64(encryptedKeyData.nonce!);
+        CryptoUtil.bin2base64(encryptedKeyData.nonce!);
 
     params["files"].add(
       CollectionFileItem(
@@ -917,8 +916,8 @@ class CollectionsService {
           file.localID = null;
         }
         final encryptedKeyData = CryptoUtil.encryptSync(key, toCollectionKey);
-        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData!);
-        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce!);
+        file.encryptedKey = CryptoUtil.bin2base64(encryptedKeyData.encryptedData!);
+        file.keyDecryptionNonce = CryptoUtil.bin2base64(encryptedKeyData.nonce!);
         params["files"].add(
           CollectionFileItem(
             file.uploadedFileID!,
@@ -983,8 +982,8 @@ class CollectionsService {
         file.collectionID = toCollectionID;
         final encryptedKeyData =
             CryptoUtil.encryptSync(fileKey, getCollectionKey(toCollectionID));
-        file.encryptedKey = Sodium.bin2base64(encryptedKeyData.encryptedData!);
-        file.keyDecryptionNonce = Sodium.bin2base64(encryptedKeyData.nonce!);
+        file.encryptedKey = CryptoUtil.bin2base64(encryptedKeyData.encryptedData!);
+        file.keyDecryptionNonce = CryptoUtil.bin2base64(encryptedKeyData.nonce!);
         params["files"].add(
           CollectionFileItem(
             file.uploadedFileID!,
@@ -1083,9 +1082,9 @@ class CollectionsService {
         final decryptionKey =
             _getAndCacheDecryptedKey(collection, source: "create");
         final utfEncodedMmd = await CryptoUtil.decryptChaCha(
-          Sodium.base642bin(collectionData['magicMetadata']['data']),
+          CryptoUtil.base642bin(collectionData['magicMetadata']['data']),
           decryptionKey,
-          Sodium.base642bin(collectionData['magicMetadata']['header']),
+          CryptoUtil.base642bin(collectionData['magicMetadata']['header']),
         );
         collection.mMdEncodedJson = utf8.decode(utfEncodedMmd);
         collection.mMdVersion = collectionData['magicMetadata']['version'];
@@ -1116,9 +1115,9 @@ class CollectionsService {
         : _config.getKey();
     return utf8.decode(
       CryptoUtil.decryptSync(
-        Sodium.base642bin(collection.attributes.encryptedPath!),
+        CryptoUtil.base642bin(collection.attributes.encryptedPath!),
         key,
-        Sodium.base642bin(collection.attributes.pathDecryptionNonce!),
+        CryptoUtil.base642bin(collection.attributes.pathDecryptionNonce!),
       ),
     );
   }
@@ -1140,9 +1139,9 @@ class CollectionsService {
           source: "Name",
         );
         final result = CryptoUtil.decryptSync(
-          Sodium.base642bin(collection.encryptedName!),
+          CryptoUtil.base642bin(collection.encryptedName!),
           collectionKey,
-          Sodium.base642bin(collection.nameDecryptionNonce!),
+          CryptoUtil.base642bin(collection.nameDecryptionNonce!),
         );
         name = utf8.decode(result);
       } catch (e, s) {

+ 4 - 5
lib/services/favorites_service.dart

@@ -3,7 +3,6 @@ import 'dart:convert';
 import 'dart:typed_data';
 
 import 'package:flutter/material.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/db/files_db.dart';
@@ -200,10 +199,10 @@ class FavoritesService {
         CryptoUtil.encryptSync(utf8.encode("Favorites") as Uint8List, key);
     final collection = await _collectionsService.createAndCacheCollection(
       CreateRequest(
-        encryptedKey: Sodium.bin2base64(encKey.encryptedData!),
-        keyDecryptionNonce: Sodium.bin2base64(encKey.nonce!),
-        encryptedName: Sodium.bin2base64(encName.encryptedData!),
-        nameDecryptionNonce: Sodium.bin2base64(encName.nonce!),
+        encryptedKey: CryptoUtil.bin2base64(encKey.encryptedData!),
+        keyDecryptionNonce: CryptoUtil.bin2base64(encKey.nonce!),
+        encryptedName: CryptoUtil.bin2base64(encName.encryptedData!),
+        nameDecryptionNonce: CryptoUtil.bin2base64(encName.nonce!),
         type: CollectionType.favorites,
         attributes: CollectionAttributes(),
       ),

+ 4 - 5
lib/services/file_magic_service.dart

@@ -2,7 +2,6 @@ import 'dart:convert';
 import 'dart:typed_data';
 
 import 'package:dio/dio.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/constants.dart';
@@ -104,8 +103,8 @@ class FileMagicService {
             magicMetadata: MetadataRequest(
               version: file.pubMmdVersion,
               count: jsonToUpdate.length,
-              data: Sodium.bin2base64(encryptedMMd.encryptedData!),
-              header: Sodium.bin2base64(encryptedMMd.header!),
+              data: CryptoUtil.bin2base64(encryptedMMd.encryptedData!),
+              header: CryptoUtil.bin2base64(encryptedMMd.header!),
             ),
           ),
         );
@@ -170,8 +169,8 @@ class FileMagicService {
               magicMetadata: MetadataRequest(
                 version: file.mMdVersion,
                 count: jsonToUpdate.length,
-                data: Sodium.bin2base64(encryptedMMd.encryptedData!),
-                header: Sodium.bin2base64(encryptedMMd.header!),
+                data: CryptoUtil.bin2base64(encryptedMMd.encryptedData!),
+                header: CryptoUtil.bin2base64(encryptedMMd.header!),
               ),
             ),
           );

+ 10 - 11
lib/services/hidden_service.dart

@@ -3,7 +3,6 @@ import 'dart:typed_data';
 
 import 'package:collection/collection.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/events/files_updated_event.dart';
@@ -140,10 +139,10 @@ extension HiddenService on CollectionsService {
         CryptoUtil.encryptSync(utf8.encode("Uncategorized") as Uint8List, key);
     final collection = await createAndCacheCollection(
       CreateRequest(
-        encryptedKey: Sodium.bin2base64(encKey.encryptedData!),
-        keyDecryptionNonce: Sodium.bin2base64(encKey.nonce!),
-        encryptedName: Sodium.bin2base64(encName.encryptedData!),
-        nameDecryptionNonce: Sodium.bin2base64(encName.nonce!),
+        encryptedKey: CryptoUtil.bin2base64(encKey.encryptedData!),
+        keyDecryptionNonce: CryptoUtil.bin2base64(encKey.nonce!),
+        encryptedName: CryptoUtil.bin2base64(encName.encryptedData!),
+        nameDecryptionNonce: CryptoUtil.bin2base64(encName.nonce!),
         type: CollectionType.uncategorized,
         attributes: CollectionAttributes(),
       ),
@@ -175,14 +174,14 @@ extension HiddenService on CollectionsService {
     final MetadataRequest metadataRequest = MetadataRequest(
       version: 1,
       count: jsonToUpdate.length,
-      data: Sodium.bin2base64(encryptedMMd.encryptedData!),
-      header: Sodium.bin2base64(encryptedMMd.header!),
+      data: CryptoUtil.bin2base64(encryptedMMd.encryptedData!),
+      header: CryptoUtil.bin2base64(encryptedMMd.header!),
     );
     final CreateRequest createRequest = CreateRequest(
-      encryptedKey: Sodium.bin2base64(encryptedKeyData.encryptedData!),
-      keyDecryptionNonce: Sodium.bin2base64(encryptedKeyData.nonce!),
-      encryptedName: Sodium.bin2base64(encryptedName.encryptedData!),
-      nameDecryptionNonce: Sodium.bin2base64(encryptedName.nonce!),
+      encryptedKey: CryptoUtil.bin2base64(encryptedKeyData.encryptedData!),
+      keyDecryptionNonce: CryptoUtil.bin2base64(encryptedKeyData.nonce!),
+      encryptedName: CryptoUtil.bin2base64(encryptedName.encryptedData!),
+      nameDecryptionNonce: CryptoUtil.bin2base64(encryptedName.nonce!),
       type: CollectionType.album,
       attributes: CollectionAttributes(),
       magicMetadata: metadataRequest,

+ 7 - 8
lib/services/user_service.dart

@@ -4,7 +4,6 @@ import 'dart:typed_data';
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:dio/dio.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/constants.dart';
@@ -569,11 +568,11 @@ class UserService {
         }
         recoveryKey = bip39.mnemonicToEntropy(recoveryKey);
       }
-      secret = Sodium.bin2base64(
+      secret = CryptoUtil.bin2base64(
         await CryptoUtil.decrypt(
-          Sodium.base642bin(encryptedSecret),
-          Sodium.hex2bin(recoveryKey.trim()),
-          Sodium.base642bin(secretDecryptionNonce),
+          CryptoUtil.base642bin(encryptedSecret),
+          CryptoUtil.hex2bin(recoveryKey.trim()),
+          CryptoUtil.base642bin(secretDecryptionNonce),
         ),
       );
     } catch (e) {
@@ -675,16 +674,16 @@ class UserService {
     final dialog = createProgressDialog(context, "Verifying...");
     await dialog.show();
     final encryptionResult =
-        CryptoUtil.encryptSync(Sodium.base642bin(secret), recoveryKey);
+        CryptoUtil.encryptSync(CryptoUtil.base642bin(secret), recoveryKey);
     try {
       await _enteDio.post(
         "/users/two-factor/enable",
         data: {
           "code": code,
           "encryptedTwoFactorSecret":
-              Sodium.bin2base64(encryptionResult.encryptedData as Uint8List),
+              CryptoUtil.bin2base64(encryptionResult.encryptedData as Uint8List),
           "twoFactorSecretDecryptionNonce":
-              Sodium.bin2base64(encryptionResult.nonce as Uint8List),
+              CryptoUtil.bin2base64(encryptionResult.nonce as Uint8List),
         },
       );
       await dialog.hide();

+ 2 - 3
lib/ui/account/delete_account_page.dart

@@ -1,7 +1,6 @@
 import 'dart:convert';
 
 import 'package:flutter/material.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/models/delete_account.dart';
 import 'package:photos/services/local_authentication_service.dart';
@@ -141,8 +140,8 @@ class DeleteAccountPage extends StatelessWidget {
         isCritical: true,
         firstButtonOnTap: () async {
           final decryptChallenge = CryptoUtil.openSealSync(
-            Sodium.base642bin(response.encryptedChallenge),
-            Sodium.base642bin(
+            CryptoUtil.base642bin(response.encryptedChallenge),
+            CryptoUtil.base642bin(
               Configuration.instance.getKeyAttributes()!.publicKey,
             ),
             Configuration.instance.getSecretKey()!,

+ 4 - 3
lib/ui/account/two_factor_setup_page.dart

@@ -3,12 +3,12 @@ import 'dart:ui';
 
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/lifecycle_event_handler.dart';
+import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:pinput/pin_put/pin_put.dart';
@@ -45,7 +45,7 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
   void initState() {
     _tabController = TabController(length: 2, vsync: this);
     _imageProvider = Image.memory(
-      Sodium.base642bin(widget.qrCode),
+      CryptoUtil.base642bin(widget.qrCode),
       height: 180,
       width: 180,
     ).image;
@@ -269,7 +269,8 @@ class _TwoFactorSetupPageState extends State<TwoFactorSetupPage>
   }
 
   void _showSuccessPage() {
-    final recoveryKey = Sodium.bin2hex(Configuration.instance.getRecoveryKey());
+    final recoveryKey =
+        CryptoUtil.bin2hex(Configuration.instance.getRecoveryKey());
     routeToPage(
       context,
       RecoveryKeyPage(

+ 3 - 3
lib/ui/account/verify_recovery_page.dart

@@ -3,7 +3,6 @@ import 'dart:ui';
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:dio/dio.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/event_bus.dart';
 import 'package:photos/ente_theme_data.dart';
@@ -14,6 +13,7 @@ import 'package:photos/services/user_service.dart';
 import 'package:photos/ui/account/recovery_key_page.dart';
 import 'package:photos/ui/common/gradient_button.dart';
 import 'package:photos/ui/components/button_widget.dart';
+import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 
@@ -33,7 +33,7 @@ class _VerifyRecoveryPageState extends State<VerifyRecoveryPage> {
     await dialog.show();
     try {
       final String inputKey = _recoveryKey.text.trim();
-      final String recoveryKey = Sodium.bin2hex(
+      final String recoveryKey = CryptoUtil.bin2hex(
         await UserService.instance.getOrCreateRecoveryKey(context),
       );
       final String recoveryKeyWords = bip39.entropyToMnemonic(recoveryKey);
@@ -97,7 +97,7 @@ class _VerifyRecoveryPageState extends State<VerifyRecoveryPage> {
     if (hasAuthenticated) {
       String recoveryKey;
       try {
-        recoveryKey = Sodium.bin2hex(
+        recoveryKey = CryptoUtil.bin2hex(
           await UserService.instance.getOrCreateRecoveryKey(context),
         );
         routeToPage(

+ 2 - 2
lib/ui/settings/account_section_widget.dart

@@ -1,7 +1,6 @@
 import 'dart:async';
 
 import 'package:flutter/material.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/services/local_authentication_service.dart';
 import 'package:photos/services/user_service.dart';
 import 'package:photos/theme/ente_theme.dart';
@@ -13,6 +12,7 @@ import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
 import 'package:photos/ui/settings/common_settings.dart';
+import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/navigation_util.dart';
 
@@ -153,7 +153,7 @@ class AccountSectionWidget extends StatelessWidget {
   }
 
   Future<String> _getOrCreateRecoveryKey(BuildContext context) async {
-    return Sodium.bin2hex(
+    return CryptoUtil.bin2hex(
       await UserService.instance.getOrCreateRecoveryKey(context),
     );
   }

+ 2 - 2
lib/ui/settings/debug_section_widget.dart

@@ -1,5 +1,4 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/services/ignored_files_service.dart';
 import 'package:photos/services/local_sync_service.dart';
@@ -10,6 +9,7 @@ import 'package:photos/ui/components/captioned_text_widget.dart';
 import 'package:photos/ui/components/expandable_menu_item_widget.dart';
 import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
 import 'package:photos/ui/settings/common_settings.dart';
+import 'package:photos/utils/crypto_util.dart';
 import 'package:photos/utils/toast_util.dart';
 
 class DebugSectionWidget extends StatelessWidget {
@@ -83,7 +83,7 @@ class DebugSectionWidget extends StatelessWidget {
               "Key",
               style: TextStyle(fontWeight: FontWeight.bold),
             ),
-            Text(Sodium.bin2base64(Configuration.instance.getKey()!)),
+            Text(CryptoUtil.bin2base64(Configuration.instance.getKey()!)),
             const Padding(padding: EdgeInsets.all(12)),
             const Text(
               "Encrypted Key",

+ 5 - 14
lib/ui/sharing/manage_links_widget.dart

@@ -5,7 +5,6 @@ import 'package:collection/collection.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:photos/ente_theme_data.dart';
 import 'package:photos/models/collection.dart';
 import 'package:photos/services/collections_service.dart';
@@ -458,24 +457,16 @@ class _ManageSharedLinkWidgetState extends State<ManageSharedLinkWidget> {
   }
 
   Future<Map<String, dynamic>> _getEncryptedPassword(String pass) async {
-    assert(
-      Sodium.cryptoPwhashAlgArgon2id13 == Sodium.cryptoPwhashAlgDefault,
-      "mismatch in expected default pw hashing algo",
-    );
-    final int memLimit = Sodium.cryptoPwhashMemlimitInteractive;
-    final int opsLimit = Sodium.cryptoPwhashOpslimitInteractive;
     final kekSalt = CryptoUtil.getSaltToDeriveKey();
-    final result = await CryptoUtil.deriveKey(
+    final result = await CryptoUtil.deriveInteractiveKey(
       utf8.encode(pass) as Uint8List,
       kekSalt,
-      memLimit,
-      opsLimit,
     );
     return {
-      'passHash': Sodium.bin2base64(result),
-      'nonce': Sodium.bin2base64(kekSalt),
-      'memLimit': memLimit,
-      'opsLimit': opsLimit,
+      'passHash': CryptoUtil.bin2base64(result.key),
+      'nonce': CryptoUtil.bin2base64(kekSalt),
+      'memLimit': result.memLimit,
+      'opsLimit': result.opsLimit,
     };
   }
 

+ 45 - 0
lib/utils/crypto_util.dart

@@ -170,6 +170,33 @@ class CryptoUtil {
     Sodium.init();
   }
 
+  static Uint8List base642bin(
+    String b64, {
+    String? ignore,
+    int variant = Sodium.base64VariantOriginal,
+  }) {
+    return Sodium.base642bin(b64, ignore: ignore, variant: variant);
+  }
+
+  static String bin2base64(
+    Uint8List bin, {
+    bool urlSafe = false,
+  }) {
+    return Sodium.bin2base64(
+      bin,
+      variant:
+          urlSafe ? Sodium.base64VariantUrlsafe : Sodium.base64VariantOriginal,
+    );
+  }
+
+  static String bin2hex(Uint8List bin) {
+    return Sodium.bin2hex(bin);
+  }
+
+  static Uint8List hex2bin(String hex) {
+    return Sodium.hex2bin(hex);
+  }
+
   static EncryptionResult encryptSync(Uint8List source, Uint8List key) {
     final nonce = Sodium.randombytesBuf(Sodium.cryptoSecretboxNoncebytes);
 
@@ -286,6 +313,10 @@ class CryptoUtil {
     Uint8List password,
     Uint8List salt,
   ) async {
+    assert(
+      Sodium.cryptoPwhashAlgArgon2id13 == Sodium.cryptoPwhashAlgDefault,
+      "mismatch in expected default pw hashing algo",
+    );
     final logger = Logger("pwhash");
     int memLimit = Sodium.cryptoPwhashMemlimitSensitive;
     int opsLimit = Sodium.cryptoPwhashOpslimitSensitive;
@@ -304,6 +335,20 @@ class CryptoUtil {
     throw UnsupportedError("Cannot perform this operation on this device");
   }
 
+  static Future<DerivedKeyResult> deriveInteractiveKey(
+    Uint8List password,
+    Uint8List salt,
+  ) async {
+    assert(
+      Sodium.cryptoPwhashAlgArgon2id13 == Sodium.cryptoPwhashAlgDefault,
+      "mismatch in expected default pw hashing algo",
+    );
+    final int memLimit = Sodium.cryptoPwhashMemlimitInteractive;
+    final int opsLimit = Sodium.cryptoPwhashOpslimitInteractive;
+    final key = await deriveKey(password, salt, memLimit, opsLimit);
+    return DerivedKeyResult(key, memLimit, opsLimit);
+  }
+
   static Future<Uint8List> deriveKey(
     Uint8List password,
     Uint8List salt,

+ 6 - 7
lib/utils/diff_fetcher.dart

@@ -1,7 +1,6 @@
 import 'dart:convert';
 import 'dart:math';
 
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/network.dart';
 import 'package:photos/db/files_db.dart';
@@ -68,18 +67,18 @@ class DiffFetcher {
 
         final fileDecryptionKey = decryptFileKey(file);
         final encodedMetadata = await CryptoUtil.decryptChaCha(
-          Sodium.base642bin(item["metadata"]["encryptedData"]),
+          CryptoUtil.base642bin(item["metadata"]["encryptedData"]),
           fileDecryptionKey,
-          Sodium.base642bin(file.metadataDecryptionHeader!),
+          CryptoUtil.base642bin(file.metadataDecryptionHeader!),
         );
         final Map<String, dynamic> metadata =
             jsonDecode(utf8.decode(encodedMetadata));
         file.applyMetadata(metadata);
         if (item['magicMetadata'] != null) {
           final utfEncodedMmd = await CryptoUtil.decryptChaCha(
-            Sodium.base642bin(item['magicMetadata']['data']),
+            CryptoUtil.base642bin(item['magicMetadata']['data']),
             fileDecryptionKey,
-            Sodium.base642bin(item['magicMetadata']['header']),
+            CryptoUtil.base642bin(item['magicMetadata']['header']),
           );
           file.mMdEncodedJson = utf8.decode(utfEncodedMmd);
           file.mMdVersion = item['magicMetadata']['version'];
@@ -88,9 +87,9 @@ class DiffFetcher {
         }
         if (item['pubMagicMetadata'] != null) {
           final utfEncodedMmd = await CryptoUtil.decryptChaCha(
-            Sodium.base642bin(item['pubMagicMetadata']['data']),
+            CryptoUtil.base642bin(item['pubMagicMetadata']['data']),
             fileDecryptionKey,
-            Sodium.base642bin(item['pubMagicMetadata']['header']),
+            CryptoUtil.base642bin(item['pubMagicMetadata']['header']),
           );
           file.pubMmdEncodedJson = utf8.decode(utfEncodedMmd);
           file.pubMmdVersion = item['pubMagicMetadata']['version'];

+ 3 - 4
lib/utils/file_download_util.dart

@@ -2,7 +2,6 @@ import 'dart:io' as io;
 import 'dart:typed_data';
 
 import 'package:dio/dio.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/configuration.dart';
 import 'package:photos/core/network.dart';
@@ -55,7 +54,7 @@ Future<io.File?> downloadAndDecrypt(
     await CryptoUtil.decryptFile(
       encryptedFilePath,
       decryptedFilePath,
-      Sodium.base642bin(file.fileDecryptionHeader!),
+      CryptoUtil.base642bin(file.fileDecryptionHeader!),
       decryptFileKey(file),
     );
     _logger.info("File decrypted: " + file.uploadedFileID.toString());
@@ -65,8 +64,8 @@ Future<io.File?> downloadAndDecrypt(
 }
 
 Uint8List decryptFileKey(ente.File file) {
-  final encryptedKey = Sodium.base642bin(file.encryptedKey!);
-  final nonce = Sodium.base642bin(file.keyDecryptionNonce!);
+  final encryptedKey = CryptoUtil.base642bin(file.encryptedKey!);
+  final nonce = CryptoUtil.base642bin(file.keyDecryptionNonce!);
   final collectionKey =
       CollectionsService.instance.getCollectionKey(file.collectionID!);
   return CryptoUtil.decryptSync(encryptedKey, collectionKey, nonce);

+ 6 - 7
lib/utils/file_uploader.dart

@@ -9,7 +9,6 @@ import 'package:collection/collection.dart';
 import 'package:connectivity/connectivity.dart';
 import 'package:dio/dio.dart';
 import 'package:flutter/foundation.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:path/path.dart';
 import 'package:photos/core/configuration.dart';
@@ -411,13 +410,13 @@ class FileUploader {
         fileAttributes.key as Uint8List,
       );
       final fileDecryptionHeader =
-          Sodium.bin2base64(fileAttributes.header as Uint8List);
+          CryptoUtil.bin2base64(fileAttributes.header as Uint8List);
       final thumbnailDecryptionHeader =
-          Sodium.bin2base64(encryptedThumbnailData.header as Uint8List);
+          CryptoUtil.bin2base64(encryptedThumbnailData.header as Uint8List);
       final encryptedMetadata =
-          Sodium.bin2base64(encryptedMetadataData.encryptedData as Uint8List);
+          CryptoUtil.bin2base64(encryptedMetadataData.encryptedData as Uint8List);
       final metadataDecryptionHeader =
-          Sodium.bin2base64(encryptedMetadataData.header as Uint8List);
+          CryptoUtil.bin2base64(encryptedMetadataData.header as Uint8List);
       if (SyncService.instance.shouldStopSync()) {
         throw SyncStopRequestedError();
       }
@@ -442,9 +441,9 @@ class FileUploader {
           CollectionsService.instance.getCollectionKey(collectionID),
         );
         final encryptedKey =
-            Sodium.bin2base64(encryptedFileKeyData.encryptedData as Uint8List);
+            CryptoUtil.bin2base64(encryptedFileKeyData.encryptedData as Uint8List);
         final keyDecryptionNonce =
-            Sodium.bin2base64(encryptedFileKeyData.nonce as Uint8List);
+            CryptoUtil.bin2base64(encryptedFileKeyData.nonce as Uint8List);
         remoteFile = await _uploadFile(
           file,
           collectionID,

+ 4 - 5
lib/utils/file_uploader_util.dart

@@ -3,7 +3,6 @@ import 'dart:io' as io;
 import 'dart:typed_data';
 
 import 'package:archive/archive_io.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:motionphoto/motionphoto.dart';
 import 'package:path/path.dart';
@@ -93,7 +92,7 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
 
   // h4ck to fetch location data if missing (thank you Android Q+) lazily only during uploads
   await _decorateEnteFileData(file, asset);
-  fileHash = Sodium.bin2base64(await CryptoUtil.getHash(sourceFile));
+  fileHash = CryptoUtil.bin2base64(await CryptoUtil.getHash(sourceFile));
 
   if (file.fileType == FileType.livePhoto && io.Platform.isIOS) {
     final io.File? videoUrl = await Motionphoto.getLivePhotoFile(file.localID!);
@@ -104,7 +103,7 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
       throw InvalidFileUploadState(errMsg);
     }
     final String livePhotoVideoHash =
-        Sodium.bin2base64(await CryptoUtil.getHash(videoUrl));
+        CryptoUtil.bin2base64(await CryptoUtil.getHash(videoUrl));
     // imgHash:vidHash
     fileHash = '$fileHash$kLivePhotoHashSeparator$livePhotoVideoHash';
     final tempPath = Configuration.instance.getTempDirectory();
@@ -122,7 +121,7 @@ Future<MediaUploadData> _getMediaUploadDataFromAssetFile(ente.File file) async {
     }
     // new sourceFile which needs to be uploaded
     sourceFile = io.File(livePhotoPath);
-    zipHash = Sodium.bin2base64(await CryptoUtil.getHash(sourceFile));
+    zipHash = CryptoUtil.bin2base64(await CryptoUtil.getHash(sourceFile));
   }
 
   thumbnailData = await asset.thumbnailDataWithSize(
@@ -177,7 +176,7 @@ Future<MediaUploadData> _getMediaUploadDataFromAppCache(ente.File file) async {
   }
   try {
     thumbnailData = await getThumbnailFromInAppCacheFile(file);
-    final fileHash = Sodium.bin2base64(await CryptoUtil.getHash(sourceFile));
+    final fileHash = CryptoUtil.bin2base64(await CryptoUtil.getHash(sourceFile));
     return MediaUploadData(
       sourceFile,
       thumbnailData,

+ 1 - 2
lib/utils/thumbnail_util.dart

@@ -4,7 +4,6 @@ import 'dart:io' as io;
 import 'dart:typed_data';
 
 import 'package:dio/dio.dart';
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photo_manager/photo_manager.dart';
 import 'package:photos/core/cache/thumbnail_in_memory_cache.dart';
@@ -151,7 +150,7 @@ Future<void> _downloadAndDecryptThumbnail(FileDownloadItem item) async {
   var data = await CryptoUtil.decryptChaCha(
     encryptedThumbnail,
     thumbnailDecryptionKey,
-    Sodium.base642bin(file.thumbnailDecryptionHeader!),
+    CryptoUtil.base642bin(file.thumbnailDecryptionHeader!),
   );
   final thumbnailSize = data.length;
   if (thumbnailSize > thumbnailDataLimit) {

+ 6 - 7
lib/utils/trash_diff_fetcher.dart

@@ -1,7 +1,6 @@
 import 'dart:convert';
 import 'dart:math';
 
-import 'package:flutter_sodium/flutter_sodium.dart';
 import 'package:logging/logging.dart';
 import 'package:photos/core/network.dart';
 import 'package:photos/models/magic_metadata.dart';
@@ -53,27 +52,27 @@ class TrashDiffFetcher {
             item["file"]["metadata"]["decryptionHeader"];
         final fileDecryptionKey = decryptFileKey(trash);
         final encodedMetadata = await CryptoUtil.decryptChaCha(
-          Sodium.base642bin(item["file"]["metadata"]["encryptedData"]),
+          CryptoUtil.base642bin(item["file"]["metadata"]["encryptedData"]),
           fileDecryptionKey,
-          Sodium.base642bin(trash.metadataDecryptionHeader!),
+          CryptoUtil.base642bin(trash.metadataDecryptionHeader!),
         );
         final Map<String, dynamic> metadata =
             jsonDecode(utf8.decode(encodedMetadata));
         trash.applyMetadata(metadata);
         if (item["file"]['magicMetadata'] != null) {
           final utfEncodedMmd = await CryptoUtil.decryptChaCha(
-            Sodium.base642bin(item["file"]['magicMetadata']['data']),
+            CryptoUtil.base642bin(item["file"]['magicMetadata']['data']),
             fileDecryptionKey,
-            Sodium.base642bin(item["file"]['magicMetadata']['header']),
+            CryptoUtil.base642bin(item["file"]['magicMetadata']['header']),
           );
           trash.mMdEncodedJson = utf8.decode(utfEncodedMmd);
           trash.mMdVersion = item["file"]['magicMetadata']['version'];
         }
         if (item["file"]['pubMagicMetadata'] != null) {
           final utfEncodedMmd = await CryptoUtil.decryptChaCha(
-            Sodium.base642bin(item["file"]['pubMagicMetadata']['data']),
+            CryptoUtil.base642bin(item["file"]['pubMagicMetadata']['data']),
             fileDecryptionKey,
-            Sodium.base642bin(item["file"]['pubMagicMetadata']['header']),
+            CryptoUtil.base642bin(item["file"]['pubMagicMetadata']['header']),
           );
           trash.pubMmdEncodedJson = utf8.decode(utfEncodedMmd);
           trash.pubMmdVersion = item["file"]['pubMagicMetadata']['version'];