ilap / pinenacl-dart

The Dart implementation of the PyNaCl API with the TweetNaCl cryptographic library
MIT License
36 stars 4 forks source link

Why ByteList.fromList need minLength and maxLength? #19

Closed anggaaryas closed 2 years ago

anggaaryas commented 2 years ago

ByteList constructor:

   ByteList.fromList(Uint8List list,
      [int minLength = _minLength, int maxLength = _maxLength])
      : _u8l = _constructList(list, minLength, maxLength);

_constructList method:

 static Uint8List _constructList(
      Iterable<int> list, int minLength, int maxLength) {
    if (list.length < minLength || list.length > maxLength) {
      throw Exception(
          'The list length (${list.length}) is invalid (min: $minLength, max: $maxLength)');
    }
    return UnmodifiableUint8ListView(Uint8List.fromList(list.toList()));
  }
ilap commented 2 years ago

Hi,

There can be different scenarios, so we want to be sure that the constructed class inherits ByteList can have some constraints (min and max size limit). For example classes:

The current naming of the constructors are misleading and I am going to release a new version the v0.5.0 with API breaks which makes more sense. Also, we do not need .fromList constructor as the main creational one use Iterable.

ilap commented 2 years ago

Released v0.5.0 check the differences.

muhammadsaddamnur commented 2 years ago

Hi @ilap i have issue when using EncryptedMessage.fromList(...) error like this:

Exception: The list length (44719) is invalid (min: 24, max: 16384)

That function have limitation with _maxLength, but i can't modify value from EncryptedMessage.fromList(...) Why doesn't add maxLength params in function? do you have any concern about that?

so, currently what i did was like this :


    Uint8List encryptedMessage = encrypted.asTypedList;
    var bytelistencryptedMessage = ByteList(
      encryptedMessage,
    );
    final takenonce =
        bytelistencryptedMessage.take(EncryptedMessage.nonceLength);
    final chipherTextnonce =
        bytelistencryptedMessage.skip(EncryptedMessage.nonceLength);
    ByteList nonce = ByteList.withConstraint(takenonce,
        constraintLength: EncryptedMessage.nonceLength);
    ByteList chipherText = ByteList.withConstraint(chipherTextnonce,
        constraintLength:
            bytelistencryptedMessage.length - EncryptedMessage.nonceLength);
    final decrypted = box.decrypt(
      EncryptedMessage(
        nonce: nonce.asTypedList,
        cipherText: chipherText.asTypedList,
      ),
    );```
ilap commented 2 years ago

Hi,

I have set it to 16K for performance reasons, but will consider some bigger size based on the benchmark, as this is not for stream en/decryption. I will create some benchmark.

ilap commented 2 years ago

I have increased it to 1MB.

ilap commented 2 years ago

so, currently what i did was like this :

Why do you do a lot of conversions? As EncryptedMessage is a ByteList and behaves like an Uint8List. The library created for the sake of simplicity where the ByteList and the extended/inherited classes behave like an Uint8List. That is why ByteList use ListMixin<int> and an internal Uint8List.

You could just simply do the following:

// encrypted can be any Iterable<int> e.g., List<int> etc.
final encryptedMessage = EncryptedMessage.fromList(encrypted.asTypedList);
final decrypted = box.decrypt(encryptedMessage);