code: public byte[] nonce(byte[] message) {
      final byte[] n1 = new byte[16];
      final byte[] n2 = new byte[16];
      final SecureRandom random = new SecureRandom();
      random.nextBytes(n1);
      random.nextBytes(n2);
  
      final Blake2bDigest blake2b = new Blake2bDigest(key, NONCE_SIZE, n1, n2);
      blake2b.update(message, message.length, 0);
  
      final byte[] nonce = new byte[NONCE_SIZE];
      blake2b.doFinal(nonce, 0);
      return nonce;
    }
docs: Generates a random nonce which is guaranteed to be unique even if the process's PRNG is
  exhausted or compromised.
  
  <p>Internally, this creates a Blake2b instance with the given key, a random 16-byte salt, and a
  random 16-byte personalization tag. It then hashes the message and returns the resulting
  24-byte digest as the nonce.
  
  <p>In the event of a broken or entropy-exhausted {@link SecureRandom} provider, the nonce is
  essentially equivalent to a synthetic IV and should be unique for any given key/message pair.
  The result will be deterministic, which will allow attackers to detect duplicate messages.
  
  <p>In the event of a compromised {@link SecureRandom} provider, the attacker would need a
  complete second-preimage attack against Blake2b in order to produce colliding nonces.
  
  @param message the message to be encrypted
  @return a 24-byte nonce