Fix/Update #1
| @ -3,7 +3,7 @@ | ||||
| // ----- | ||||
| // File: native_crypto.dart | ||||
| // Created Date: 16/12/2021 16:28:00 | ||||
| // Last Modified: 25/05/2022 10:48:20 | ||||
| // Last Modified: 26/05/2022 12:10:42 | ||||
| // ----- | ||||
| // Copyright (c) 2021 | ||||
| 
 | ||||
| @ -23,7 +23,6 @@ export 'src/kdf/kdf.dart'; | ||||
| export 'src/keys/keys.dart'; | ||||
| // Utils | ||||
| export 'src/utils/cipher_algorithm.dart'; | ||||
| export 'src/utils/convert.dart'; | ||||
| export 'src/utils/hash_algorithm.dart'; | ||||
| export 'src/utils/kdf_algorithm.dart'; | ||||
| 
 | ||||
|  | ||||
| @ -3,81 +3,144 @@ | ||||
| // ----- | ||||
| // File: cipher_text.dart | ||||
| // Created Date: 16/12/2021 16:59:53 | ||||
| // Last Modified: 24/05/2022 21:27:44 | ||||
| // Last Modified: 26/05/2022 16:22:49 | ||||
| // ----- | ||||
| // Copyright (c) 2021 | ||||
| 
 | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:native_crypto/src/interfaces/byte_array.dart'; | ||||
| import 'package:native_crypto/src/utils/cipher_algorithm.dart'; | ||||
| import 'package:native_crypto/src/utils/extensions.dart'; | ||||
| import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; | ||||
| 
 | ||||
| class CipherText extends ByteArray { | ||||
| /// Represents a cipher text in Native Crypto. | ||||
| /// | ||||
| /// It is represented as a [List] of [Uint8List] like: | ||||
| /// ```txt | ||||
| /// [[NONCE], [MESSAGE + TAG]] | ||||
| /// ``` | ||||
| /// where: | ||||
| /// - `[NONCE]` is a [Uint8List] of length [CipherText.ivLength] | ||||
| /// - `[MESSAGE + TAG]` is a [Uint8List] of length [CipherText.dataLength] | ||||
| ///  | ||||
| /// To  | ||||
| /// | ||||
| /// So accessing just the Message or just the Tag is costly and should be  | ||||
| /// done only when needed. | ||||
| class CipherText { | ||||
|   final int _ivLength; | ||||
|   final int _dataLength; | ||||
|   final int _messageLength; | ||||
|   final int _tagLength; | ||||
| 
 | ||||
|   final Uint8List _iv; | ||||
|   final CipherAlgorithm? _cipherAlgorithm; | ||||
| 
 | ||||
|   CipherText(Uint8List iv, Uint8List data, Uint8List? tag) | ||||
|       : _ivLength = iv.length, | ||||
|         _dataLength = data.length, | ||||
|         _tagLength = tag?.length ?? 0, | ||||
|         _iv = iv, | ||||
|         super((tag != null) ? Uint8List.fromList(data + tag) : data); | ||||
|   final Uint8List? _iv; | ||||
|   final Uint8List? _data; // Contains the message + tag (if any) | ||||
| 
 | ||||
|   CipherText.fromBytes( | ||||
|     Uint8List bytes, { | ||||
|     required int ivLength, | ||||
|     required int dataLength, | ||||
|     int tagLength = 0, | ||||
|   })  : _ivLength = ivLength, | ||||
|         _dataLength = dataLength, | ||||
|         _tagLength = tagLength, | ||||
|         _iv = bytes.sublist(0, ivLength), | ||||
|         super(bytes.sublist(ivLength, bytes.length - tagLength)); | ||||
|   CipherText._( | ||||
|     this._ivLength, | ||||
|     this._messageLength, | ||||
|     this._tagLength, | ||||
|     this._cipherAlgorithm, | ||||
|     this._iv, | ||||
|     this._data, | ||||
|   ); | ||||
| 
 | ||||
|   const CipherText.fromIvAndBytes( | ||||
|     Uint8List iv, | ||||
|     super.data, { | ||||
|     required int dataLength, | ||||
|     int tagLength = 0, | ||||
|   })  : _ivLength = iv.length, | ||||
|         _dataLength = dataLength, | ||||
|         _tagLength = tagLength, | ||||
|         _iv = iv; | ||||
|   /// Gets the [CipherAlgorithm] used to encrypt the [CipherText]. | ||||
|   CipherAlgorithm get cipherAlgorithm { | ||||
|     if (_cipherAlgorithm.isNotNull) { | ||||
|       return _cipherAlgorithm!; | ||||
|     } else { | ||||
|       throw NativeCryptoException( | ||||
|         message: 'Cipher algorithm is not specified', | ||||
|         code: NativeCryptoExceptionCode.invalid_cipher.code, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   CipherText.fromPairIvAndBytes( | ||||
|     List<Uint8List> pair, { | ||||
|     required int dataLength, | ||||
|     int tagLength = 0, | ||||
|   })  : _ivLength = pair.first.length, | ||||
|         _dataLength = dataLength, | ||||
|         _tagLength = tagLength, | ||||
|         _iv = pair.first, | ||||
|         super(pair.last); | ||||
|   /// Gets the [Uint8List] of the [CipherText]'s IV. | ||||
|   Uint8List get iv { | ||||
|     if (_iv.isNotNull) { | ||||
|       return _iv!; | ||||
|     } else { | ||||
|       throw NativeCryptoException( | ||||
|         message: 'IV is not specified', | ||||
|         code: NativeCryptoExceptionCode.invalid_data.code, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /// Gets the CipherText IV. | ||||
|   Uint8List get iv => _iv; | ||||
| 
 | ||||
|   /// Gets the CipherText data. | ||||
|   Uint8List get data => _tagLength > 0 | ||||
|       ? bytes.sublist(0, _dataLength - _tagLength) | ||||
|       : bytes; | ||||
| 
 | ||||
|   /// Gets the CipherText tag. | ||||
|   Uint8List get tag => _tagLength > 0 | ||||
|       ? bytes.sublist(_dataLength - _tagLength, _dataLength) | ||||
|       : Uint8List(0); | ||||
| 
 | ||||
|   /// Gets the CipherText data and tag. | ||||
|   Uint8List get payload => bytes; | ||||
| 
 | ||||
|   /// Gets the CipherText IV length. | ||||
|   /// Gets the length of the [CipherText]'s IV. | ||||
|   int get ivLength => _ivLength; | ||||
| 
 | ||||
|   /// Gets the CipherText data length. | ||||
|   int get dataLength => _dataLength; | ||||
|   /// Gets the [Uint8List] of the [CipherText]'s data. | ||||
|   Uint8List get data { | ||||
|     if (_data.isNotNull) { | ||||
|       return _data!; | ||||
|     } else { | ||||
|       throw NativeCryptoException( | ||||
|         message: 'Data is not specified', | ||||
|         code: NativeCryptoExceptionCode.invalid_data.code, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /// Gets the CipherText tag length. | ||||
|   int get tagLength => _tagLength; | ||||
|   /// Gets the length of the [CipherText]'s data. | ||||
|   int get dataLength => _messageLength + _tagLength; | ||||
| 
 | ||||
|   // CipherText.fromBytes( | ||||
|   //   Uint8List bytes, { | ||||
|   //   required int ivLength, | ||||
|   //   required int dataLength, | ||||
|   //   int tagLength = 0, | ||||
|   // })  : _ivLength = ivLength, | ||||
|   //       _dataLength = dataLength, | ||||
|   //       _tagLength = tagLength, | ||||
|   //       _iv = bytes.sublist(0, ivLength), | ||||
|   //       super(bytes.sublist(ivLength, bytes.length - tagLength)); | ||||
| 
 | ||||
|   // const CipherText.fromIvAndBytes( | ||||
|   //   Uint8List iv, | ||||
|   //   super.data, { | ||||
|   //   required int dataLength, | ||||
|   //   int tagLength = 0, | ||||
|   // })  : _ivLength = iv.length, | ||||
|   //       _dataLength = dataLength, | ||||
|   //       _tagLength = tagLength, | ||||
|   //       _iv = iv; | ||||
| 
 | ||||
|   // CipherText.fromPairIvAndBytes( | ||||
|   //   List<Uint8List> pair, { | ||||
|   //   required int dataLength, | ||||
|   //   int tagLength = 0, | ||||
|   // })  : _ivLength = pair.first.length, | ||||
|   //       _dataLength = dataLength, | ||||
|   //       _tagLength = tagLength, | ||||
|   //       _iv = pair.first, | ||||
|   //       super(pair.last); | ||||
| 
 | ||||
|   // /// Gets the CipherText IV. | ||||
|   // Uint8List get iv => _iv; | ||||
| 
 | ||||
|   // /// Gets the CipherText data. | ||||
|   // Uint8List get data => _tagLength > 0 | ||||
|   //     ? bytes.sublist(0, _dataLength - _tagLength) | ||||
|   //     : bytes; | ||||
| 
 | ||||
|   // /// Gets the CipherText tag. | ||||
|   // Uint8List get tag => _tagLength > 0 | ||||
|   //     ? bytes.sublist(_dataLength - _tagLength, _dataLength) | ||||
|   //     : Uint8List(0); | ||||
| 
 | ||||
|   // /// Gets the CipherText data and tag. | ||||
|   // Uint8List get payload => bytes; | ||||
| 
 | ||||
|   // /// Gets the CipherText IV length. | ||||
|   // int get ivLength => _ivLength; | ||||
| 
 | ||||
|   // /// Gets the CipherText data length. | ||||
|   // int get dataLength => _dataLength; | ||||
| 
 | ||||
|   // /// Gets the CipherText tag length. | ||||
|   // int get tagLength => _tagLength; | ||||
| } | ||||
|  | ||||
							
								
								
									
										89
									
								
								packages/native_crypto/lib/src/core/cipher_text_wrapper.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								packages/native_crypto/lib/src/core/cipher_text_wrapper.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: cipher_text_wrapper.dart | ||||
| // Created Date: 26/05/2022 14:27:32 | ||||
| // Last Modified: 26/05/2022 15:53:46 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:native_crypto/native_crypto.dart'; | ||||
| import 'package:native_crypto/src/utils/extensions.dart'; | ||||
| 
 | ||||
| class CipherTextWrapper { | ||||
|   final CipherText? _single; | ||||
|   final List<CipherText>? _list; | ||||
| 
 | ||||
|   CipherTextWrapper._(this._single, this._list); | ||||
| 
 | ||||
|   factory CipherTextWrapper.single(CipherText cipherText) => | ||||
|       CipherTextWrapper._(cipherText, null); | ||||
| 
 | ||||
|   factory CipherTextWrapper.list(List<CipherText> cipherTexts) => | ||||
|       CipherTextWrapper._(null, cipherTexts); | ||||
| 
 | ||||
|   factory CipherTextWrapper.fromBytes( | ||||
|       // Uint8List bytes, { | ||||
|       // required int ivLength, | ||||
|       // required int dataLength, | ||||
|       // int tagLength = 0, | ||||
|       // int? chunkSize, | ||||
|       // } | ||||
|       ) { | ||||
|         // TODO(hpcl): implement fromBytes | ||||
|     throw UnimplementedError(); | ||||
|   } | ||||
| 
 | ||||
|   bool get isSingle => _single.isNotNull; | ||||
|   bool get isList => _list.isNotNull; | ||||
| 
 | ||||
|   /// Gets the [CipherText] if it's a single one. | ||||
|   /// | ||||
|   /// Throws [NativeCryptoException] with | ||||
|   /// [NativeCryptoExceptionCode.invalid_data] if it's not a single one. | ||||
|   CipherText get single { | ||||
|     if (isSingle) { | ||||
|       return _single!; | ||||
|     } else { | ||||
|       throw NativeCryptoException( | ||||
|         message: 'CipherTextWrapper is not single', | ||||
|         code: NativeCryptoExceptionCode.invalid_data.code, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /// Gets the [List] of [CipherText] if it's a list. | ||||
|   /// | ||||
|   /// Throws [NativeCryptoException] with | ||||
|   /// [NativeCryptoExceptionCode.invalid_data] if it's not a list. | ||||
|   List<CipherText> get list { | ||||
|     if (isList) { | ||||
|       return _list!; | ||||
|     } else { | ||||
|       throw NativeCryptoException( | ||||
|         message: 'CipherTextWrapper is not list', | ||||
|         code: NativeCryptoExceptionCode.invalid_data.code, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /// Gets the raw [Uint8List] of the [CipherText] or [List] of [CipherText]. | ||||
|   Uint8List get raw { | ||||
|     if (isSingle) { | ||||
|       return single.bytes; | ||||
|     } else { | ||||
|       return list.map((cipherText) => cipherText.bytes).toList().sum(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   int get chunkCount { | ||||
|     _single.isNull; | ||||
|     if (_single.isNotNull) { | ||||
|       return 1; | ||||
|     } else { | ||||
|       return _list?.length ?? 0; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -3,47 +3,58 @@ | ||||
| // ----- | ||||
| // File: byte_array.dart | ||||
| // Created Date: 16/12/2021 17:54:16 | ||||
| // Last Modified: 23/05/2022 23:07:03 | ||||
| // Last Modified: 26/05/2022 14:25:05 | ||||
| // ----- | ||||
| // Copyright (c) 2021 | ||||
| 
 | ||||
| import 'dart:convert' as convert; | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:flutter/foundation.dart'; | ||||
| import 'package:native_crypto/src/utils/convert.dart'; | ||||
| import 'package:native_crypto/src/utils/encoding.dart'; | ||||
| import 'package:native_crypto/src/utils/extensions.dart'; | ||||
| 
 | ||||
| @immutable | ||||
| abstract class ByteArray { | ||||
|   final Uint8List _bytes; | ||||
| 
 | ||||
|   /// Creates a [ByteArray] from a [Uint8List]. | ||||
|   const ByteArray(this._bytes); | ||||
| 
 | ||||
|   /// Creates an ByteArray object from a hexdecimal string. | ||||
|   /// Creates a [ByteArray] object from a hexdecimal string. | ||||
|   ByteArray.fromBase16(String encoded) | ||||
|       : _bytes = Convert.decodeHexString(encoded); | ||||
|       : _bytes = encoded.toBytes(from: Encoding.base16); | ||||
| 
 | ||||
|   /// Creates an ByteArray object from a Base64 string. | ||||
|   /// Creates a [ByteArray] object from a Base64 string. | ||||
|   ByteArray.fromBase64(String encoded) | ||||
|       : _bytes = convert.base64.decode(encoded); | ||||
|       : _bytes = encoded.toBytes(from: Encoding.base64); | ||||
| 
 | ||||
|   /// Creates an ByteArray object from a UTF-8 string. | ||||
|   ByteArray.fromUtf8(String input) | ||||
|       : _bytes = Uint8List.fromList(convert.utf8.encode(input)); | ||||
|   /// Creates a [ByteArray] object from an UTF-8 string. | ||||
|   ByteArray.fromUtf8(String encoded) | ||||
|       : _bytes = encoded.toBytes(from: Encoding.utf8); | ||||
| 
 | ||||
|   /// Creates an ByteArray object from a length. | ||||
|   /// Creates a [ByteArray] object from an UTF-16 string. | ||||
|   ByteArray.fromUtf16(String encoded) : _bytes = encoded.toBytes(); | ||||
| 
 | ||||
|   /// Creates an empty [ByteArray] object from a length. | ||||
|   ByteArray.fromLength(int length) : _bytes = Uint8List(length); | ||||
| 
 | ||||
|   /// Gets the ByteArray bytes. | ||||
|   // ignore: unnecessary_getters_setters | ||||
|   /// Creates a [ByteArray] object from a [List] of [int]. | ||||
|   ByteArray.fromList(List<int> list) : _bytes = list.toTypedList(); | ||||
| 
 | ||||
|   /// Gets the [ByteArray] bytes. | ||||
|   Uint8List get bytes => _bytes; | ||||
| 
 | ||||
|   /// Gets the ByteArray bytes as a Hexadecimal representation. | ||||
|   String get base16 => | ||||
|       _bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(); | ||||
|   /// Gets the [ByteArray] bytes as a Hexadecimal representation. | ||||
|   String get base16 => _bytes.toStr(to: Encoding.base16); | ||||
| 
 | ||||
|   /// Gets the ByteArray bytes as a Base64 representation. | ||||
|   String get base64 => convert.base64.encode(_bytes); | ||||
|   /// Gets the [ByteArray] bytes as a Base64 representation. | ||||
|   String get base64 => _bytes.toStr(to: Encoding.base64); | ||||
| 
 | ||||
|   /// Gets the [ByteArray] bytes as an UTF-8 representation. | ||||
|   String get utf8 => _bytes.toStr(to: Encoding.utf8); | ||||
| 
 | ||||
|   /// Gets the [ByteArray] bytes as an UTF-16 representation. | ||||
|   String get utf16 => _bytes.toStr(); | ||||
| 
 | ||||
|   @override | ||||
|   bool operator ==(Object other) { | ||||
|  | ||||
| @ -3,7 +3,7 @@ | ||||
| // ----- | ||||
| // File: secret_key.dart | ||||
| // Created Date: 28/12/2021 13:36:54 | ||||
| // Last Modified: 25/05/2022 10:45:55 | ||||
| // Last Modified: 26/05/2022 11:56:06 | ||||
| // ----- | ||||
| // Copyright (c) 2021 | ||||
| 
 | ||||
| @ -24,13 +24,22 @@ class SecretKey extends Key { | ||||
| 
 | ||||
|   static Future<SecretKey> fromSecureRandom(int bitsCount) async { | ||||
|     try { | ||||
|       final Uint8List _key = | ||||
|           (await platform.generateSecretKey(bitsCount)) ?? Uint8List(0); | ||||
|       final Uint8List? _key = await platform.generateSecretKey(bitsCount); | ||||
| 
 | ||||
|       if (_key == null || _key.isEmpty) { | ||||
|         throw const KeyException( | ||||
|           message: 'Could not generate secret key, platform returned null', | ||||
|           code: 'platform_returned_null', | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|       return SecretKey(_key); | ||||
|     } catch (e, s) { | ||||
|       if (e is KeyException) { | ||||
|         rethrow; | ||||
|       } | ||||
|       throw KeyException( | ||||
|         message: 'Failed to generate a secret key!', | ||||
|         message: '$e', | ||||
|         code: 'failed_to_generate_secret_key', | ||||
|         stackTrace: s, | ||||
|       ); | ||||
|  | ||||
| @ -1,23 +0,0 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: convert.dart | ||||
| // Created Date: 16/12/2021 16:28:00 | ||||
| // Last Modified: 23/05/2022 22:39:19 | ||||
| // ----- | ||||
| // Copyright (c) 2021 | ||||
| 
 | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| abstract class Convert { | ||||
|   static Uint8List decodeHexString(String input) { | ||||
|     assert(input.length.isEven, 'Input needs to be an even length.'); | ||||
| 
 | ||||
|     return Uint8List.fromList( | ||||
|       List.generate( | ||||
|         input.length ~/ 2, | ||||
|         (i) => int.parse(input.substring(i * 2, (i * 2) + 2), radix: 16), | ||||
|       ).toList(), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										10
									
								
								packages/native_crypto/lib/src/utils/encoding.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								packages/native_crypto/lib/src/utils/encoding.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: encoding.dart | ||||
| // Created Date: 26/05/2022 12:12:34 | ||||
| // Last Modified: 26/05/2022 12:18:09 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| enum Encoding { utf8, utf16, base64, base16 } | ||||
							
								
								
									
										95
									
								
								packages/native_crypto/lib/src/utils/extensions.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								packages/native_crypto/lib/src/utils/extensions.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: extensions.dart | ||||
| // Created Date: 26/05/2022 12:12:48 | ||||
| // Last Modified: 26/05/2022 15:49:38 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| import 'dart:convert'; | ||||
| import 'dart:developer' as developer; | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:native_crypto/src/utils/encoding.dart'; | ||||
| 
 | ||||
| extension ObjectX on Object? { | ||||
|   /// Returns `true` if the object is `null`. | ||||
|   bool get isNull => this == null; | ||||
| 
 | ||||
|   /// Returns `true` if the object is **not** `null`. | ||||
|   bool get isNotNull => this != null; | ||||
|    | ||||
|   /// Prints the object to the console. | ||||
|   void log() => developer.log(toString()); | ||||
| } | ||||
| 
 | ||||
| extension ListIntX on List<int> { | ||||
|   /// Converts a [List] of int to a [Uint8List]. | ||||
|   Uint8List toTypedList() => Uint8List.fromList(this); | ||||
| } | ||||
| 
 | ||||
| extension ListUint8ListX on List<Uint8List> { | ||||
|   /// Reduce a [List] of [Uint8List] to a [Uint8List]. | ||||
| 
 | ||||
|   Uint8List sum() { | ||||
|     for (var i = 1; i < length; i++) { | ||||
|       first.addAll(this[i]); | ||||
|       removeAt(i); | ||||
|     } | ||||
|     return first; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| extension StringX on String { | ||||
|   /// Converts a [String] to a [Uint8List] using the specified [Encoding]. | ||||
|   Uint8List toBytes({final Encoding from = Encoding.utf16}) { | ||||
|     Uint8List bytes; | ||||
|     switch (from) { | ||||
|       case Encoding.utf8: | ||||
|         bytes = utf8.encode(this).toTypedList(); | ||||
|         break; | ||||
|       case Encoding.utf16: | ||||
|         bytes = runes.toList().toTypedList(); | ||||
|         break; | ||||
|       case Encoding.base64: | ||||
|         bytes = base64.decode(this); | ||||
|         break; | ||||
|       case Encoding.base16: | ||||
|         assert(length.isEven, 'String needs to be an even length.'); | ||||
|         bytes = List.generate( | ||||
|           length ~/ 2, | ||||
|           (i) => int.parse(substring(i * 2, (i * 2) + 2), radix: 16), | ||||
|         ).toList().toTypedList(); | ||||
|     } | ||||
|     return bytes; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| extension Uint8ListX on Uint8List { | ||||
|   /// Converts a [Uint8List] to a [String] using the specified [Encoding]. | ||||
|   String toStr({final Encoding to = Encoding.utf16}) { | ||||
|     String str; | ||||
|     switch (to) { | ||||
|       case Encoding.utf8: | ||||
|         str = utf8.decode(this); | ||||
|         break; | ||||
|       case Encoding.utf16: | ||||
|         str = String.fromCharCodes(this); | ||||
|         break; | ||||
|       case Encoding.base64: | ||||
|         str = base64.encode(this); | ||||
|         break; | ||||
|       case Encoding.base16: | ||||
|         str = List.generate( | ||||
|           length, | ||||
|           (i) => this[i].toRadixString(16).padLeft(2, '0'), | ||||
|         ).join(); | ||||
|     } | ||||
|     return str; | ||||
|   } | ||||
| 
 | ||||
|   /// Returns a concatenation of this with the other [Uint8List]. | ||||
|   Uint8List operator +(final Uint8List other) => | ||||
|       [...this, ...other].toTypedList(); | ||||
| } | ||||
| @ -3,21 +3,41 @@ | ||||
| // ----- | ||||
| // File: exception.dart | ||||
| // Created Date: 24/05/2022 18:54:48 | ||||
| // Last Modified: 25/05/2022 10:43:29 | ||||
| // Last Modified: 26/05/2022 15:36:56 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| // ignore_for_file: constant_identifier_names | ||||
| 
 | ||||
| import 'dart:developer'; | ||||
| 
 | ||||
| import 'package:flutter/services.dart'; | ||||
| 
 | ||||
| enum NativeCryptoExceptionCode { | ||||
|   unknown, | ||||
|   not_implemented, | ||||
|   invalid_argument, | ||||
|   invalid_key, | ||||
|   invalid_key_length, | ||||
|   invalid_algorithm, | ||||
|   invalid_padding, | ||||
|   invalid_mode, | ||||
|   invalid_cipher, | ||||
|   invalid_data, | ||||
|   platform_not_supported, | ||||
|   platform_returned_invalid_data, | ||||
|   platform_returned_empty_data, | ||||
|   platform_returned_null; | ||||
| 
 | ||||
|   String get code => toString().split('.').last.toLowerCase(); | ||||
| } | ||||
| 
 | ||||
| class NativeCryptoException implements Exception { | ||||
|   const NativeCryptoException({ | ||||
|   NativeCryptoException({ | ||||
|     this.message, | ||||
|     String? code, | ||||
|     this.stackTrace, | ||||
|     // ignore: unnecessary_this | ||||
|   }) : this.code = code ?? 'unknown'; | ||||
|   }) : code = code ?? NativeCryptoExceptionCode.unknown.code; | ||||
| 
 | ||||
|   /// The long form message of the exception. | ||||
|   final String? message; | ||||
| @ -73,7 +93,7 @@ class NativeCryptoException implements Exception { | ||||
|           ) | ||||
|         : null; | ||||
| 
 | ||||
|     String code = 'unknown'; | ||||
|     String code = NativeCryptoExceptionCode.unknown.code; | ||||
|     String message = platformException.message ?? ''; | ||||
| 
 | ||||
|     if (details != null) { | ||||
| @ -103,51 +123,3 @@ class NativeCryptoException implements Exception { | ||||
|   // ignore: avoid_equals_and_hash_code_on_mutable_classes | ||||
|   int get hashCode => message.hashCode ^ code.hashCode ^ stackTrace.hashCode; | ||||
| } | ||||
| 
 | ||||
| class KeyException extends NativeCryptoException { | ||||
|   const KeyException({ | ||||
|     super.message, | ||||
|     super.code, | ||||
|     super.stackTrace, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class KeyDerivationException extends NativeCryptoException { | ||||
|   const KeyDerivationException({ | ||||
|     super.message, | ||||
|     super.code, | ||||
|     super.stackTrace, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class CipherInitException extends NativeCryptoException { | ||||
|   const CipherInitException({ | ||||
|     super.message, | ||||
|     super.code, | ||||
|     super.stackTrace, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class EncryptionException extends NativeCryptoException { | ||||
|   const EncryptionException({ | ||||
|     super.message, | ||||
|     super.code, | ||||
|     super.stackTrace, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class DecryptionException extends NativeCryptoException { | ||||
|   const DecryptionException({ | ||||
|     super.message, | ||||
|     super.code, | ||||
|     super.stackTrace, | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| class NotImplementedException extends NativeCryptoException { | ||||
|   const NotImplementedException({ | ||||
|     super.message, | ||||
|     super.code, | ||||
|     super.stackTrace, | ||||
|   }); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user