public static byte[] HashSaltPersonal(byte[] message, byte[] key, byte[] salt, byte[] personal, int bytes = 64) { if (message == null) { throw new ArgumentNullException("message", "Message cannot be null"); } if (salt == null) { throw new ArgumentNullException("salt", "Salt cannot be null"); } if (personal == null) { throw new ArgumentNullException("personal", "Personal string cannot be null"); } if (key != null && (key.Length > 64 || key.Length < 16)) { throw new KeyOutOfRangeException(string.Format("key must be between {0} and {1} bytes in length.", 16, 64)); } if (key == null) { key = new byte[0]; } if (salt.Length != 16) { throw new SaltOutOfRangeException(string.Format("Salt must be {0} bytes in length.", 16)); } if (personal.Length != 16) { throw new PersonalOutOfRangeException(string.Format("Personal bytes must be {0} bytes in length.", 16)); } if (bytes > 64 || bytes < 16) { throw new BytesOutOfRangeException("bytes", bytes, string.Format("bytes must be between {0} and {1} bytes in length.", 16, 64)); } byte[] array = new byte[bytes]; SodiumLibrary.crypto_generichash_blake2b_salt_personal(array, array.Length, message, (long)message.Length, key, key.Length, salt, personal); return(array); }