@startuml

title Authenticated Encryptions

abstract class BoxBase extends ByteList implements AsymmetricKey {
  + Crypting doEncrypt;
  + Crypting doDecrypt;
  + ByteList get key;

  + Uint8List decrypt(Uint8List encryptedMessage, {Uint8List nonce})
  + EncryptedMessage encrypt(List<int> plainText, {List<int> nonce})
}

class SecretBox extends BoxBase {
  + static const keyLength = TweetNaCl.keyLength;
  + static const macBytes = TweetNaCl.macBytes;
  + ByteList get key => this;

  + Crypting doEncrypt = TweetNaCl.crypto_box_afternm;
  + Crypting doDecrypt = TweetNaCl.crypto_box_open_afternm;
}

class Box extends BoxBase {
  + ByteList get sharedKey => this;
  + ByteList get key => sharedKey;

  + Crypting doEncrypt = TweetNaCl.crypto_box_afternm;
  + Crypting doDecrypt = TweetNaCl.crypto_box_open_afternm;

  + static ByteList _beforeNm(...);
}

class SealedBox extends ByteList implements AsymmetricKey {
  - final PrivateKey _privateKey;

  - static const _zerobytesLength = TweetNaCl.zerobytesLength;
  - static const _nonceLength = 24;
  - static const _pubLength = TweetNaCl.publicKeyLength;
  - static const _secretLength = TweetNaCl.secretKeyLength;
  - static const _macBytes = TweetNaCl.macBytes;
  - static const _sealBytes = _pubLength + _macBytes;

  + Uint8List decrypt(Uint8List ciphertext)
  + Uint8List encrypt(List<int> plaintext)

  - static void _generateNonce(Uint8List out, Uint8List in1, Uint8List in2)
  - Uint8List _cryptoBoxSeal(Uint8List message, ByteList pk)
  - void _cryptoBoxDetached(...)
  - Uint8List _cryptoBoxSealOpen(Uint8List ciphertext);
}

@enduml
