Fix/Update #1
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: cipher_page.dart | // File: cipher_page.dart | ||||||
| // Created Date: 28/12/2021 13:33:15 | // Created Date: 28/12/2021 13:33:15 | ||||||
| // Last Modified: 26/05/2022 20:39:37 | // Last Modified: 26/05/2022 21:07:54 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2021 | // Copyright (c) 2021 | ||||||
| 
 | 
 | ||||||
| @ -26,7 +26,8 @@ class CipherPage extends ConsumerWidget { | |||||||
|   final Output encryptionStatus = Output(); |   final Output encryptionStatus = Output(); | ||||||
|   final Output decryptionStatus = Output(); |   final Output decryptionStatus = Output(); | ||||||
| 
 | 
 | ||||||
|   final TextEditingController _plainTextController = TextEditingController()..text = 'PlainText'; |   final TextEditingController _plainTextController = TextEditingController() | ||||||
|  |     ..text = 'PlainText'; | ||||||
|   CipherTextWrapper? cipherText; |   CipherTextWrapper? cipherText; | ||||||
| 
 | 
 | ||||||
|   Future<void> _encrypt(WidgetRef ref, Cipher cipher) async { |   Future<void> _encrypt(WidgetRef ref, Cipher cipher) async { | ||||||
| @ -58,9 +59,10 @@ class CipherPage extends ConsumerWidget { | |||||||
|       // Recreate cipher text with altered data |       // Recreate cipher text with altered data | ||||||
|       cipherText = CipherTextWrapper.fromBytes( |       cipherText = CipherTextWrapper.fromBytes( | ||||||
|         _altered, |         _altered, | ||||||
|         12, |         ivLength: AESMode.gcm.ivLength, | ||||||
|         _altered.length - 28, |         messageLength: | ||||||
|         16, |             _altered.length - (AESMode.gcm.ivLength + AESMode.gcm.tagLength), | ||||||
|  |         tagLength: AESMode.gcm.tagLength, | ||||||
|       ); |       ); | ||||||
|       encryptionStatus.print('String successfully encrypted:\n'); |       encryptionStatus.print('String successfully encrypted:\n'); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: kdf_page.dart | // File: kdf_page.dart | ||||||
| // Created Date: 28/12/2021 13:40:34 | // Created Date: 28/12/2021 13:40:34 | ||||||
| // Last Modified: 26/05/2022 20:30:31 | // Last Modified: 26/05/2022 21:09:47 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2021 | // Copyright (c) 2021 | ||||||
| 
 | 
 | ||||||
| @ -26,8 +26,10 @@ class KdfPage extends ConsumerWidget { | |||||||
|   final Output pbkdf2Status = Output(); |   final Output pbkdf2Status = Output(); | ||||||
|   final Output hashStatus = Output(large: true); |   final Output hashStatus = Output(large: true); | ||||||
| 
 | 
 | ||||||
|   final TextEditingController _pwdTextController = TextEditingController()..text = 'Password'; |   final TextEditingController _pwdTextController = TextEditingController() | ||||||
|   final TextEditingController _messageTextController = TextEditingController()..text = 'Message'; |     ..text = 'Password'; | ||||||
|  |   final TextEditingController _messageTextController = TextEditingController() | ||||||
|  |     ..text = 'Message'; | ||||||
| 
 | 
 | ||||||
|   Future<void> _generate(WidgetRef ref) async { |   Future<void> _generate(WidgetRef ref) async { | ||||||
|     Session state = ref.read(sessionProvider.state).state; |     Session state = ref.read(sessionProvider.state).state; | ||||||
| @ -50,7 +52,11 @@ class KdfPage extends ConsumerWidget { | |||||||
|     if (password.isEmpty) { |     if (password.isEmpty) { | ||||||
|       pbkdf2Status.print('Password is empty'); |       pbkdf2Status.print('Password is empty'); | ||||||
|     } else { |     } else { | ||||||
|       Pbkdf2 _pbkdf2 = Pbkdf2(32, 1000, algorithm: HashAlgorithm.sha512); |       Pbkdf2 _pbkdf2 = Pbkdf2( | ||||||
|  |         keyBytesCount: 32, | ||||||
|  |         iterations: 1000, | ||||||
|  |         algorithm: HashAlgorithm.sha512, | ||||||
|  |       ); | ||||||
|       SecretKey sk = await _pbkdf2.derive(password: password, salt: 'salt'); |       SecretKey sk = await _pbkdf2.derive(password: password, salt: 'salt'); | ||||||
|       state.setKey(sk); |       state.setKey(sk); | ||||||
|       pbkdf2Status.print('Key successfully derived.'); |       pbkdf2Status.print('Key successfully derived.'); | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: aes.dart | // File: aes.dart | ||||||
| // Created Date: 16/12/2021 16:28:00 | // Created Date: 16/12/2021 16:28:00 | ||||||
| // Last Modified: 26/05/2022 19:43:22 | // Last Modified: 26/05/2022 21:07:01 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2022 | // Copyright (c) 2022 | ||||||
| 
 | 
 | ||||||
| @ -21,6 +21,10 @@ import 'package:native_crypto/src/utils/cipher_algorithm.dart'; | |||||||
| import 'package:native_crypto/src/utils/extensions.dart'; | import 'package:native_crypto/src/utils/extensions.dart'; | ||||||
| import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; | import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; | ||||||
| 
 | 
 | ||||||
|  | export 'aes_key_size.dart'; | ||||||
|  | export 'aes_mode.dart'; | ||||||
|  | export 'aes_padding.dart'; | ||||||
|  | 
 | ||||||
| /// An AES cipher. | /// An AES cipher. | ||||||
| /// | /// | ||||||
| /// [AES] is a [Cipher] that can be used to encrypt or decrypt data. | /// [AES] is a [Cipher] that can be used to encrypt or decrypt data. | ||||||
| @ -94,11 +98,11 @@ class AES implements Cipher { | |||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
|       return CipherText.fromBytes( |       return CipherText.fromBytes( | ||||||
|         12, |  | ||||||
|         encrypted.length - 28, |  | ||||||
|         16, |  | ||||||
|         CipherAlgorithm.aes, |  | ||||||
|         encrypted, |         encrypted, | ||||||
|  |         ivLength: 12, | ||||||
|  |         messageLength: encrypted.length - 28, | ||||||
|  |         tagLength: 16, | ||||||
|  |         cipherAlgorithm: CipherAlgorithm.aes, | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: aes_mode.dart | // File: aes_mode.dart | ||||||
| // Created Date: 23/05/2022 22:09:16 | // Created Date: 23/05/2022 22:09:16 | ||||||
| // Last Modified: 26/05/2022 18:41:31 | // Last Modified: 26/05/2022 21:03:26 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2022 | // Copyright (c) 2022 | ||||||
| 
 | 
 | ||||||
| @ -11,10 +11,20 @@ import 'package:native_crypto/src/ciphers/aes/aes_padding.dart'; | |||||||
| 
 | 
 | ||||||
| /// Defines the AES modes of operation. | /// Defines the AES modes of operation. | ||||||
| enum AESMode { | enum AESMode { | ||||||
|   gcm([AESPadding.none]); |   gcm([AESPadding.none], 12, 16); | ||||||
| 
 | 
 | ||||||
|   /// Returns the list of supported [AESPadding] for this [AESMode]. |   /// Returns the list of supported [AESPadding] for this [AESMode]. | ||||||
|   final List<AESPadding> supportedPaddings; |   final List<AESPadding> supportedPaddings; | ||||||
| 
 | 
 | ||||||
|   const AESMode(this.supportedPaddings); |   /// Returns the default IV length for this [AESMode]. | ||||||
|  |   final int ivLength; | ||||||
|  | 
 | ||||||
|  |   /// Returns the default tag length for this [AESMode]. | ||||||
|  |   final int tagLength; | ||||||
|  | 
 | ||||||
|  |   const AESMode( | ||||||
|  |     this.supportedPaddings, [ | ||||||
|  |     this.ivLength = 16, | ||||||
|  |     this.tagLength = 0, | ||||||
|  |   ]); | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: cipher_text.dart | // File: cipher_text.dart | ||||||
| // Created Date: 16/12/2021 16:59:53 | // Created Date: 16/12/2021 16:59:53 | ||||||
| // Last Modified: 26/05/2022 19:43:57 | // Last Modified: 26/05/2022 22:20:40 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2021 | // Copyright (c) 2021 | ||||||
| 
 | 
 | ||||||
| @ -45,16 +45,33 @@ class CipherText extends ByteArray { | |||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
|   factory CipherText.fromBytes( |   factory CipherText.fromBytes( | ||||||
|     int ivLength, |     Uint8List bytes, { | ||||||
|     int messageLength, |     required int ivLength, | ||||||
|     int tagLength, |     required int messageLength, | ||||||
|  |     required int tagLength, | ||||||
|     CipherAlgorithm? cipherAlgorithm, |     CipherAlgorithm? cipherAlgorithm, | ||||||
|     Uint8List bytes, |   }) { | ||||||
|   ) { |     if (ivLength.isNegative || | ||||||
|  |         messageLength.isNegative || | ||||||
|  |         tagLength.isNegative) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: 'Invalid length! Must be positive.', | ||||||
|  |         code: NativeCryptoExceptionCode.invalid_argument.code, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (bytes.isEmpty) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: 'Passed data is empty!', | ||||||
|  |         code: NativeCryptoExceptionCode.invalid_argument.code, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (bytes.length != ivLength + messageLength + tagLength) { |     if (bytes.length != ivLength + messageLength + tagLength) { | ||||||
|       throw NativeCryptoException( |       throw NativeCryptoException( | ||||||
|         message: 'Invalid cipher text length! ' |         message: 'Invalid cipher text length! ' | ||||||
|             'Expected: ${ivLength + messageLength + tagLength} bytes', |             'Expected: ${ivLength + messageLength + tagLength} bytes ' | ||||||
|  |             'got: ${bytes.length} bytes.', | ||||||
|         code: NativeCryptoExceptionCode.invalid_argument.code, |         code: NativeCryptoExceptionCode.invalid_argument.code, | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: cipher_text_wrapper.dart | // File: cipher_text_wrapper.dart | ||||||
| // Created Date: 26/05/2022 14:27:32 | // Created Date: 26/05/2022 14:27:32 | ||||||
| // Last Modified: 26/05/2022 20:32:38 | // Last Modified: 26/05/2022 22:11:42 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2022 | // Copyright (c) 2022 | ||||||
| 
 | 
 | ||||||
| @ -49,10 +49,10 @@ class CipherTextWrapper { | |||||||
|   /// [NativeCryptoExceptionCode.invalid_argument] if the [Uint8List] is |   /// [NativeCryptoExceptionCode.invalid_argument] if the [Uint8List] is | ||||||
|   /// not a valid [CipherText] or a [List] of [CipherText]. |   /// not a valid [CipherText] or a [List] of [CipherText]. | ||||||
|   factory CipherTextWrapper.fromBytes( |   factory CipherTextWrapper.fromBytes( | ||||||
|     Uint8List bytes, |     Uint8List bytes, { | ||||||
|     int ivLength, |     required int ivLength, | ||||||
|     int messageLength, |     required int messageLength, | ||||||
|     int tagLength, { |     required int tagLength, | ||||||
|     CipherAlgorithm? cipherAlgorithm, |     CipherAlgorithm? cipherAlgorithm, | ||||||
|     int? chunkSize, |     int? chunkSize, | ||||||
|   }) { |   }) { | ||||||
| @ -62,11 +62,11 @@ class CipherTextWrapper { | |||||||
|     if (bytes.length <= chunkSize) { |     if (bytes.length <= chunkSize) { | ||||||
|       return CipherTextWrapper.single( |       return CipherTextWrapper.single( | ||||||
|         CipherText.fromBytes( |         CipherText.fromBytes( | ||||||
|           ivLength, |  | ||||||
|           messageLength, |  | ||||||
|           tagLength, |  | ||||||
|           cipherAlgorithm, |  | ||||||
|           bytes, |           bytes, | ||||||
|  |           ivLength: ivLength, | ||||||
|  |           messageLength: messageLength, | ||||||
|  |           tagLength: tagLength, | ||||||
|  |           cipherAlgorithm: cipherAlgorithm, | ||||||
|         ), |         ), | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
| @ -75,11 +75,11 @@ class CipherTextWrapper { | |||||||
|         final chunk = bytes.sublist(i, i + chunkSize); |         final chunk = bytes.sublist(i, i + chunkSize); | ||||||
|         cipherTexts.add( |         cipherTexts.add( | ||||||
|           CipherText.fromBytes( |           CipherText.fromBytes( | ||||||
|             ivLength, |  | ||||||
|             messageLength, |  | ||||||
|             tagLength, |  | ||||||
|             cipherAlgorithm, |  | ||||||
|             chunk, |             chunk, | ||||||
|  |             ivLength: ivLength, | ||||||
|  |             messageLength: messageLength, | ||||||
|  |             tagLength: tagLength, | ||||||
|  |             cipherAlgorithm: cipherAlgorithm, | ||||||
|           ), |           ), | ||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
| @ -128,7 +128,7 @@ class CipherTextWrapper { | |||||||
|     if (isSingle) { |     if (isSingle) { | ||||||
|       return single.bytes; |       return single.bytes; | ||||||
|     } else { |     } else { | ||||||
|       return list.map((cipherText) => cipherText.bytes).toList().sum(); |       return list.map((cipherText) => cipherText.bytes).toList().combine(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: cipher.dart | // File: cipher.dart | ||||||
| // Created Date: 16/12/2021 16:28:00 | // Created Date: 16/12/2021 16:28:00 | ||||||
| // Last Modified: 26/05/2022 17:38:26 | // Last Modified: 26/05/2022 21:21:07 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2021 | // Copyright (c) 2021 | ||||||
| 
 | 
 | ||||||
| @ -20,7 +20,11 @@ import 'package:native_crypto/src/utils/cipher_algorithm.dart'; | |||||||
| ///  | ///  | ||||||
| /// This interface is implemented by all the ciphers in NativeCrypto. | /// This interface is implemented by all the ciphers in NativeCrypto. | ||||||
| abstract class Cipher { | abstract class Cipher { | ||||||
|   static int _bytesCountPerChunk = 33554432; |   static const int _bytesCountPerChunkDefault = 33554432; | ||||||
|  |   static int _bytesCountPerChunk = _bytesCountPerChunkDefault; | ||||||
|  | 
 | ||||||
|  |   /// Returns the default number of bytes per chunk. | ||||||
|  |   static int get defaultBytesCountPerChunk => _bytesCountPerChunkDefault; | ||||||
| 
 | 
 | ||||||
|   /// Returns the size of a chunk of data  |   /// Returns the size of a chunk of data  | ||||||
|   /// that can be processed by the [Cipher]. |   /// that can be processed by the [Cipher]. | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: pbkdf2.dart | // File: pbkdf2.dart | ||||||
| // Created Date: 17/12/2021 14:50:42 | // Created Date: 17/12/2021 14:50:42 | ||||||
| // Last Modified: 26/05/2022 18:51:59 | // Last Modified: 26/05/2022 23:19:46 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2021 | // Copyright (c) 2021 | ||||||
| 
 | 
 | ||||||
| @ -29,31 +29,64 @@ class Pbkdf2 extends KeyDerivation { | |||||||
|   @override |   @override | ||||||
|   KdfAlgorithm get algorithm => KdfAlgorithm.pbkdf2; |   KdfAlgorithm get algorithm => KdfAlgorithm.pbkdf2; | ||||||
| 
 | 
 | ||||||
|   Pbkdf2( |   Pbkdf2({ | ||||||
|     int keyBytesCount, |     required int keyBytesCount, | ||||||
|     int iterations, { |     required int iterations, | ||||||
|     HashAlgorithm algorithm = HashAlgorithm.sha256, |     HashAlgorithm algorithm = HashAlgorithm.sha256, | ||||||
|   })  : _keyBytesCount = keyBytesCount, |   })  : _keyBytesCount = keyBytesCount, | ||||||
|         _iterations = iterations, |         _iterations = iterations, | ||||||
|         _hash = algorithm; |         _hash = algorithm { | ||||||
| 
 |     if (keyBytesCount < 0) { | ||||||
|   @override |  | ||||||
|   Future<SecretKey> derive({String? password, String? salt}) async { |  | ||||||
|     if (password == null || salt == null) { |  | ||||||
|       throw NativeCryptoException( |       throw NativeCryptoException( | ||||||
|         message: 'Password and salt cannot be null. ' |         message: 'keyBytesCount must be positive.', | ||||||
|             'Here is the password: $password, here is the salt: $salt', |  | ||||||
|         code: NativeCryptoExceptionCode.invalid_argument.code, |         code: NativeCryptoExceptionCode.invalid_argument.code, | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     final Uint8List? derivation = await platform.pbkdf2( |     if (iterations <= 0) { | ||||||
|       password, |       throw NativeCryptoException( | ||||||
|       salt, |         message: 'iterations must be strictly positive.', | ||||||
|  |         code: NativeCryptoExceptionCode.invalid_argument.code, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Future<SecretKey> derive({String? password, String? salt}) async { | ||||||
|  |     Uint8List? derivation; | ||||||
|  | 
 | ||||||
|  |     if (_keyBytesCount == 0) { | ||||||
|  |       return SecretKey(Uint8List(0)); | ||||||
|  |     } | ||||||
|  |     if (password.isNull) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: 'Password cannot be null.', | ||||||
|  |         code: NativeCryptoExceptionCode.invalid_argument.code, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (salt.isNull) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: 'Salt cannot be null.', | ||||||
|  |         code: NativeCryptoExceptionCode.invalid_argument.code, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |       derivation = await platform.pbkdf2( | ||||||
|  |         password!, | ||||||
|  |         salt!, | ||||||
|         _keyBytesCount, |         _keyBytesCount, | ||||||
|         _iterations, |         _iterations, | ||||||
|         _hash.name, |         _hash.name, | ||||||
|       ); |       ); | ||||||
|  |     } catch (e, s) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: '$e', | ||||||
|  |         code: NativeCryptoExceptionCode.platform_throws.code, | ||||||
|  |         stackTrace: s, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (derivation.isNull) { |     if (derivation.isNull) { | ||||||
|       throw NativeCryptoException( |       throw NativeCryptoException( | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: secret_key.dart | // File: secret_key.dart | ||||||
| // Created Date: 28/12/2021 13:36:54 | // Created Date: 28/12/2021 13:36:54 | ||||||
| // Last Modified: 26/05/2022 19:26:35 | // Last Modified: 26/05/2022 23:13:10 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2021 | // Copyright (c) 2021 | ||||||
| 
 | 
 | ||||||
| @ -28,6 +28,10 @@ class SecretKey extends BaseKey { | |||||||
| 
 | 
 | ||||||
|   static Future<SecretKey> fromSecureRandom(int bitsCount) async { |   static Future<SecretKey> fromSecureRandom(int bitsCount) async { | ||||||
|     Uint8List? key; |     Uint8List? key; | ||||||
|  |     if (bitsCount == 0) { | ||||||
|  |       return SecretKey(Uint8List(0)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     try { |     try { | ||||||
|       key = await platform.generateSecretKey(bitsCount); |       key = await platform.generateSecretKey(bitsCount); | ||||||
|     } catch (e, s) { |     } catch (e, s) { | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: extensions.dart | // File: extensions.dart | ||||||
| // Created Date: 26/05/2022 12:12:48 | // Created Date: 26/05/2022 12:12:48 | ||||||
| // Last Modified: 26/05/2022 18:52:48 | // Last Modified: 26/05/2022 22:15:33 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2022 | // Copyright (c) 2022 | ||||||
| 
 | 
 | ||||||
| @ -30,14 +30,10 @@ extension ListIntX on List<int> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| extension ListUint8ListX on List<Uint8List> { | extension ListUint8ListX on List<Uint8List> { | ||||||
|    |  | ||||||
|   /// Reduce a [List] of [Uint8List] to a [Uint8List]. |   /// Reduce a [List] of [Uint8List] to a [Uint8List]. | ||||||
|   Uint8List sum() { |   Uint8List combine() { | ||||||
|     for (var i = 1; i < length; i++) { |     if (isEmpty) return Uint8List(0); | ||||||
|       first.addAll(this[i]); |     return reduce((value, element) => value.plus(element)); | ||||||
|       removeAt(i); |  | ||||||
|     } |  | ||||||
|     return first; |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -90,6 +86,5 @@ extension Uint8ListX on Uint8List { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /// Returns a concatenation of this with the other [Uint8List]. |   /// Returns a concatenation of this with the other [Uint8List]. | ||||||
|   Uint8List operator +(final Uint8List other) => |   Uint8List plus(final Uint8List other) => [...this, ...other].toTypedList(); | ||||||
|       [...this, ...other].toTypedList(); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,13 +3,15 @@ | |||||||
| // ----- | // ----- | ||||||
| // File: hash_algorithm.dart | // File: hash_algorithm.dart | ||||||
| // Created Date: 23/05/2022 22:01:59 | // Created Date: 23/05/2022 22:01:59 | ||||||
| // Last Modified: 26/05/2022 18:53:38 | // Last Modified: 26/05/2022 22:59:04 | ||||||
| // ----- | // ----- | ||||||
| // Copyright (c) 2022 | // Copyright (c) 2022 | ||||||
| 
 | 
 | ||||||
| import 'dart:typed_data'; | import 'dart:typed_data'; | ||||||
| 
 | 
 | ||||||
| import 'package:native_crypto/src/platform.dart'; | import 'package:native_crypto/src/platform.dart'; | ||||||
|  | import 'package:native_crypto/src/utils/extensions.dart'; | ||||||
|  | import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; | ||||||
| 
 | 
 | ||||||
| /// Defines the hash algorithms. | /// Defines the hash algorithms. | ||||||
| enum HashAlgorithm { | enum HashAlgorithm { | ||||||
| @ -19,7 +21,30 @@ enum HashAlgorithm { | |||||||
| 
 | 
 | ||||||
|   /// Digest the [data] using this [HashAlgorithm]. |   /// Digest the [data] using this [HashAlgorithm]. | ||||||
|   Future<Uint8List> digest(Uint8List data) async { |   Future<Uint8List> digest(Uint8List data) async { | ||||||
|     final Uint8List hash = (await platform.digest(data, name)) ?? Uint8List(0); |     Uint8List? hash; | ||||||
|  |     try { | ||||||
|  |       hash = await platform.digest(data, name); | ||||||
|  |     } catch (e, s) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: '$e', | ||||||
|  |         code: NativeCryptoExceptionCode.platform_throws.code, | ||||||
|  |         stackTrace: s, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (hash.isNull) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: 'Failed to digest data! Platform returned null.', | ||||||
|  |         code: NativeCryptoExceptionCode.platform_returned_null.code, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (hash!.isEmpty) { | ||||||
|  |       throw NativeCryptoException( | ||||||
|  |         message: 'Failed to digest data! Platform returned no data.', | ||||||
|  |         code: NativeCryptoExceptionCode.platform_returned_empty_data.code, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return hash; |     return hash; | ||||||
|   } |   } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user