aboutsummaryrefslogblamecommitdiffstats
path: root/libhashsum.h
blob: 65c3a668b7a667846b8a9dc74c3a863fa220a634 (plain) (tree)
1
2
3
4
5
6
7






                                                         








                                         


                                        
 



                                                                   
                                                         


                              
                            




                    

              

                           
                       

                                                                                               





















                                                                                  
                                                 



                                                    
                                                    



                                                                 




                                                                         

              




                                                                         

              




                                                                         

              




                                                                                

              




                                                                                

              




                                                                                

              




                                                                                

              


                                          

                                                                          

              




                                                                          

              


                                    

                                                                             

              




                                                                             

              




                                                                             

              




                                                                             

              




                                                                                 

              




                                                                                 

              


                                           

































































































                                                                                  



























                                                                              
 





                                          











                                      
                                    










                                         
                              








                                        
                               










                                         
                                     












                                         
                                      










                                         
                                      












                                         
                                      
 
                                       


                                       
                                             
      
 
                                       


                                       
                                         









                                         
                                
                                  
                                           
      
 



                                                 

                                    



                                                 

                                    



                                                 

                                    



                                                 

                                    


                                                          



                                                                                   




                                   

              



                                  

                      



                                            










                                             

                                                

                      




                                                    

                      








                                                             

                                                         

                      




                                                               

                      










                                                                      

                      







                                                                                          






                                                                
                                                                           
                                                  


                                                                                   


                                                                                         

                      

                             
                                                                                                                   




                                                 






                                                                
                                                                           
                                                                                        




                                                                                       


                                                                                         

                      




                                                                                                                    











                                                                    


                           

                      




                                     




                           







                                                                                 
                                                 

                                                                     
                                                                              
                                                                        





                                                                                
                                               

              




                                                                                                













                                                                                                     








                                                                                 





                                                                                
                                               






                                                                                              

                                                



                                                                            
                                                        

              




                                                               

                                                



                                                                            
                                                        

              




                                                               

                                                



                                                                            
                                                        

              




                                                               

                                                



                                                                            
                                                        

              




                                                                      

                                                



                                                                            
                                                        

              




                                                                      

                                                



                                                                            
                                                        

              




                                                                      

                                                



                                                                            
                                                        

              



                                                                      
   

                                                



                                                                            
                                                        

              




                                                                

                                                



                                                                            
                                                        

              



                                                                






                                                                            
                                                        

              










                                                                            
                                                        

              










                                                                            
                                                        

              










                                                                            
                                                        

              










                                                                            
                                                        

              










                                                                            
                                                        

              
















                                                                                
                                                        

              



                                                                                                    



































































                                                                                
                                                                                       








                                                                  

                                                                                    



























































































































































































































                                                                                                      




                                                                            
                                                           






                                                        
                                                                                      





                                                                            
                                                           






                                                        
                                                                                      






                                                                                
                                                               







                                                               
                                                                                                     





                                                                            
                                                           






                                                        
                                                                                      





                                                                            
                                                           






                                                        
                                                                                      






                                                                                
                                                               







                                                               
                                                                                                     




                                                


                                                                                 
                                                                                   


                                                                             

                                                                          

                                                                       




                                                        
                                                                                                                      
 

      
/* See LICENSE file for copyright and license details. */
#ifndef LIBHASHSUM_H
#define LIBHASHSUM_H

#include <stddef.h>
#include <stdint.h>

#ifdef LIBHASHSUM_INCLUDE_LIBSHA1_STATE
# include <libsha1.h>
#endif
#ifdef LIBHASHSUM_INCLUDE_LIBSHA2_STATE
# include <libsha2.h>
#endif
#ifdef LIBHASHSUM_INCLUDE_LIBKECCAK_STATE
# include <libkeccak.h>
#endif
#ifdef LIBHASHSUM_INCLUDE_LIBBLAKE_STATE
# include <libblake.h>
#endif


#if defined(__GNUC__)
# define LIBHASHSUM_USERET_ __attribute__((__warn_unused_result__))
# define LIBHASHSUM_1_NONNULL_ __attribute__((__nonnull__(1)))
# define LIBHASHSUM_NONNULL_ __attribute__((__nonnull__))
#else
# define LIBHASHSUM_USERET_
# define LIBHASHSUM_1_NONNULL_
# define LIBHASHSUM_NONNULL_
#endif


/**
 * Hashing algorithm
 * 
 * @since  1.0
 */
enum libhashsum_algorithm {
	/* since 1.0 */
	LIBHASHSUM_MD2,          /**< MD2; this algorithm has been theoretically compromised */
	LIBHASHSUM_MD4,          /**< MD4; this algorithm has been compromised */
	LIBHASHSUM_MD5,          /**< MD5; this algorithm has been compromised */
	LIBHASHSUM_RIPEMD_128,   /**< RIPEMD-128 */
	LIBHASHSUM_RIPEMD_160,   /**< RIPEMD-160 */
	LIBHASHSUM_RIPEMD_256,   /**< RIPEMD-256 */
	LIBHASHSUM_RIPEMD_320,   /**< RIPEMD-320 */
	LIBHASHSUM_SHA0,         /**< SHA0; this algorithm has been compromised */
	LIBHASHSUM_SHA1,         /**< SHA1; this algorithm has been compromised */
	LIBHASHSUM_SHA_224,      /**< SHA-224 (SHA2) */
	LIBHASHSUM_SHA_256,      /**< SHA-256 (SHA2) */
	LIBHASHSUM_SHA_384,      /**< SHA-384 (SHA2) */
	LIBHASHSUM_SHA_512,      /**< SHA-512 (SHA2) */
	LIBHASHSUM_SHA_512_224,  /**< SHA-512/224 (SHA2) */
	LIBHASHSUM_SHA_512_256,  /**< SHA-512/256 (SHA2) */
	LIBHASHSUM_KECCAK,       /**< Keccak[] */
	LIBHASHSUM_KECCAK_224,   /**< Keccak-224 */
	LIBHASHSUM_KECCAK_256,   /**< Keccak-256 */
	LIBHASHSUM_KECCAK_384,   /**< Keccak-384 */
	LIBHASHSUM_KECCAK_512,   /**< Keccak-512 */
	LIBHASHSUM_SHA3_224,     /**< SHA3-224 */
	LIBHASHSUM_SHA3_256,     /**< SHA3-256 */
	LIBHASHSUM_SHA3_384,     /**< SHA3-384 */
	LIBHASHSUM_SHA3_512,     /**< SHA3-512 */
	LIBHASHSUM_SHAKE128,     /**< SHAKE128 */
	LIBHASHSUM_SHAKE256,     /**< SHAKE256 */
	LIBHASHSUM_SHAKE512,     /**< SHAKE512 */
	LIBHASHSUM_RAWSHAKE128,  /**< RawSHAKE128 */
	LIBHASHSUM_RAWSHAKE256,  /**< RawSHAKE256 */
	LIBHASHSUM_RAWSHAKE512,  /**< RawSHAKE512 */
	LIBHASHSUM_BLAKE224,     /**< BLAKE224 (BLAKE, BLAKEs) */
	LIBHASHSUM_BLAKE256,     /**< BLAKE256 (BLAKE, BLAKEs) */
	LIBHASHSUM_BLAKE384,     /**< BLAKE384 (BLAKE, BLAKEb) */
	LIBHASHSUM_BLAKE512      /**< BLAKE512 (BLAKE, BLAKEb) */
};


/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD2`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_MD2_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD4`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_MD4_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD5`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_MD5_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_128`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_RIPEMD_128_HASH_SIZE 16

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_160`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_RIPEMD_160_HASH_SIZE 20

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_RIPEMD_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_320`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_RIPEMD_320_HASH_SIZE 40

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA0`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA0_HASH_SIZE 20

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA1`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA1_HASH_SIZE 20

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_224`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA_224_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_384`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA_384_HASH_SIZE 48

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_512`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA_512_HASH_SIZE 64

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_512_224`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA_512_224_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA_512_256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA_512_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_224`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_KECCAK_224_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_KECCAK_256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_KECCAK_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_KECCAK_384`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_KECCAK_384_HASH_SIZE 48

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_KECCAK_512`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_KECCAK_512_HASH_SIZE 64

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_224`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA3_224_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA3_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_384`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA3_384_HASH_SIZE 48

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_512`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHA3_512_HASH_SIZE 64

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE_128`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHAKE_128_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE_256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHAKE_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE_512`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_SHAKE_512_HASH_SIZE 64

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE_128`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_RAWSHAKE_128_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE_256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_RAWSHAKE_256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE_512`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_RAWSHAKE_512_HASH_SIZE 64

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_BLAKE224`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_BLAKE224_HASH_SIZE 28

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_BLAKE256`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_BLAKE256_HASH_SIZE 32

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_BLAKE384`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_BLAKE384_HASH_SIZE 48

/**
 * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_BLAKE512`
 * 
 * @since  1.0
 */
#define LIBHASHSUM_BLAKE512_HASH_SIZE 64


#if defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpadded"
#endif


/**
 * Hash state
 * 
 * For internal use
 */
union libhashsum_state {
	struct {
		unsigned char x[32];
		unsigned char mp[16];
		unsigned char mz[16];
		unsigned char sum[16];
		unsigned t;
	} md2; /* size = [82, 88] */

	struct {
		union {
			uint32_t h32[4];
			uint8_t sum[16];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint64_t count;
	} md4; /* size = 70 */

	struct {
		union {
			uint32_t h32[4];
			uint8_t sum[16];
		} h;
		uint8_t m[64];
		uint32_t w[16];
		uint64_t count;
	} md5; /* size = 152 */

	struct {
		union {
			uint32_t h32[4];
			uint8_t sum[16];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint64_t count;
	} ripemd_128; /* size = 88 */

	struct {
		union {
			uint32_t h32[5];
			uint8_t sum[20];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint32_t w1[5];
		uint32_t w2[5];
		uint64_t count;
	} ripemd_160; /* size = 132 */

	struct {
		union {
			uint32_t h32[8];
			uint8_t sum[32];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint64_t count;
	} ripemd_256; /* size = 104 */

	struct {
		union {
			uint32_t h32[10];
			uint8_t sum[40];
		} h;
		union {
			uint32_t m32[16];
			uint8_t m8[64];
		} m;
		uint32_t w1[5];
		uint32_t w2[5];
		uint64_t count;
	} ripemd_320; /* size = 152 */

#ifdef LIBHASHSUM_INCLUDE_LIBSHA1_STATE
	struct {
		struct libsha1_state s;
		uint8_t sum[20];
	} sha0, sha1; /* size = [432, 440] */
#endif

#ifdef LIBHASHSUM_INCLUDE_LIBSHA2_STATE
	struct {
		struct libsha2_state s;
		uint8_t sum[64];
	} sha2; /* size = [1612, 1624] */
#endif

#ifdef LIBHASHSUM_INCLUDE_LIBKECCAK_STATE
	struct {
		struct libkeccak_state s;
		union {
			uint8_t buf[512];
			uint8_t *dyn;
		} sum;
		const char *suffix;
		size_t squeezes;
		char algostr[256];
	} keccak; /* size = [1024, 1072] */
#endif

#ifdef LIBHASHSUM_INCLUDE_LIBBLAKE_STATE
	struct {
		struct libblake_blake224_state s;
		uint8_t buf[128];
		char algostr[49];
	} blake224; /* size = 233 */

	struct {
		struct libblake_blake256_state s;
		uint8_t buf[128];
		char algostr[49];
	} blake256; /* size = 233 */

	struct {
		struct libblake_blake384_state s;
		uint8_t buf[256];
		char algostr[81];
	} blake384; /* size = 449 */

	struct {
		struct libblake_blake512_state s;
		uint8_t buf[256];
		char algostr[81];
	} blake512; /* size = 449 */
#endif

	/* libblake: 48(2s), 96(2b), 144(2Xs), 276(2Xb) */

	char max_size[1648];
#define libhashsum_init_hasher libhashsum_init_hasher__1648
#define libhashsum_init_hasher_from_string libhashsum_init_hasher_from_string__1648
};


/**
 * Message hash functions and state
 * 
 * @since  1.0
 */
struct libhashsum_hasher {
	/**
	 * The used hash algorithm
	 * 
	 * @since  1.0
	 */
	enum libhashsum_algorithm algorithm;

	/**
	 * A string describing the used hash
	 * algorithm and parameters
	 * 
	 * This may be pointer to a buffer in
	 * `.state`
	 * 
	 * @since  1.0
	 */
	const char *algorithm_string;

	/**
	 * The number of bytes required for each
	 * call to `.process_block`
	 * 
	 * @since  1.0
	 */
	size_t input_block_size;

	/**
	 * The number of bytes in the resulting hash
	 * 
	 * @since  1.0
	 */
	size_t hash_size;

	/**
	 * The hash
	 * 
	 * This will be set to `NULL` when the structure
	 * is initialised, but will be set to a pointer
	 * to a buffer inside `.state` once `.finalise_const`
	 * or `.finalise` has been called with successful
	 * completion
	 * 
	 * @since  1.0
	 */
	unsigned char *hash_output;

	/**
	 * Whether the algorithm supports non-whole octet input
	 * 
	 * @since  1.0
	 */
	unsigned char supports_non_whole_bytes;

	/**
	 * Update the hash state given additional
	 * input data
	 * 
	 * @param   this   The object containing this function pointer
	 * @param   data   The new input data
	 * @param   bytes  The number of bytes available in `data`
	 * @return         The number of bytes processed from `data`
	 * 
	 * @since  1.0
	 */
	LIBHASHSUM_USERET_ LIBHASHSUM_1_NONNULL_
	size_t (*process)(struct libhashsum_hasher *this, const void *data, size_t bytes);

	/**
	 * Update the hash state given it's final
	 * input data
	 * 
	 * Regardless of the algorithm's standard, the function
	 * will takes the lower bits from `data[bytes]`, if
	 * `extra_bits > 0` and use the for the additional bits;
	 * the least significant bit will be used as the first
	 * bit and the most significant bit will be used as the
	 * last bit
	 * 
	 * @param   this        The object containing this function pointer
	 * @param   data        The new input data
	 * @param   bytes       The number of bytes available in `data` for reading
	 * @param   extra_bits  Additional bits in `data` not covered by `bytes`
	 * @return              0 on success, -1 on failure
	 * 
	 * @throws  EINVAL  `extra_bits` is greater than 7
	 * @throws  EINVAL  `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0
	 * 
	 * @since  1.0
	 */
	LIBHASHSUM_1_NONNULL_
	int (*finalise_const)(struct libhashsum_hasher *this, const void *data, size_t bytes, unsigned extra_bits);

	/**
	 * Update the hash state given it's final
	 * input data
	 * 
	 * Regardless of the algorithm's standard, the function
	 * will takes the lower bits from `data[bytes]`, if
	 * `extra_bits > 0` and use the for the additional bits;
	 * the least significant bit will be used as the first
	 * bit and the most significant bit will be used as the
	 * last bit
	 * 
	 * @param   this        The object containing this function pointer
	 * @param   data        The new input data, the function may rewrite its content
	 * @param   bytes       The number of bytes available in `data` for reading
	 * @param   extra_bits  Additional bits in `data` not covered by `bytes`
	 * @param   size        `bytes` plus any number of additional bytes available
	 *                      for the function to write additional data block padding
	 * @return              0 on success, -1 on failure
	 * 
	 * @throws  EINVAL  `extra_bits` is greater than 7
	 * @throws  EINVAL  `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0
	 * 
	 * @since  1.0
	 */
	LIBHASHSUM_1_NONNULL_
	int (*finalise)(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size);

	/**
	 * Unless this pointer its `NULL`, it points to
	 * function that shall be once the object (`this`)
	 * is not needed anymore
	 * 
	 * @param  this  The object containing this function pointer
	 * 
	 * @since  1.0
	 */
	LIBHASHSUM_1_NONNULL_
	void (*destroy)(struct libhashsum_hasher *this);

	/**
	 * The hash state
	 * 
	 * For internal use
	 * 
	 * @since  1.0
	 */
	union libhashsum_state state;
};


#if defined(__GNUC__)
# pragma GCC diagnostic pop
#endif


/**
 * Create an initialised state for a hash algorithm
 * and return hash functions and details
 * 
 * @param   this       The output parameter for the functions, details, and state
 * @param   algorithm  The hashing algorithm
 * @return             0 on success, -1 on failure
 * 
 * @throws  EINVAL  `algorithm` is not recognised
 * @throws  EINVAL  `algorithm` requires parameters, and is therefore
 *                  not supported by this function (use dedicated
 *                  initialiser instead). (`algorithm` is `LIBHASHSUM_KECCAK`)
 * @throws  ENOSYS  Support for `algorithm` was excluded at compile time
 * @throws  ENOSYS  The `algorithm` requires a newer version of the library
 *                  that application was compiled for (the application
 *                  is however linked to new enough version of the library)
 *                  (specifically this means that the application's version
 *                  of `union libhashsum_state`, and thus also
 *                  `struct libhashsum_hasher`, is too small to store the state)
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algorithm algorithm);

/**
 * Inspect a hashing algorithm string to identify
 * which algorithm it references
 * 
 * @param   algorithm_out  Output parameter for the hashing algorithm
 *                         identifier (set if 1 is returned)
 * @param   algorithm      The hashing algorithm as a string
 * @return                 1 if the algorithm was recognised, 0 otherwise
 * 
 * @since  1.0
 */
LIBHASHSUM_NONNULL_
int libhashsum_get_algorithm_string(enum libhashsum_algorithm *algorithm_out, const char *algorithm);

/**
 * Create an initialised state for a hash algorithm
 * and return hash functions and details
 * 
 * @param   this       The output parameter for the functions, details, and state
 * @param   algorithm  The hashing algorithm and parameters
 * @return             0 on success, -1 on failure
 * 
 * @throws  EINVAL  `algorithm` is not recognised or contains an invalid value
 * @throws  ENOSYS  Support for `algorithm` was excluded at compile time
 * @throws  ENOSYS  The `algorithm` requires a newer version of the library
 *                  that application was compiled for (the application
 *                  is however linked to new enough version of the library)
 *                  (specifically this means that the application's version
 *                  of `union libhashsum_state`, and thus also
 *                  `struct libhashsum_hasher`, is too small to store the state)
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_NONNULL_
int libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *algorithm);

/**
 * Create an initialised state for MD2
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_md2_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for MD4
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_md4_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for MD5
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_md5_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-128
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_128_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-160
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_160_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-256
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for RIPEMD-320
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_ripemd_320_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA0
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha0_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA1
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha1_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-224 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_224_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-256 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-384 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_384_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-512 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_512_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-512/224 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_512_224_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA-512/256 (SHA2)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha_512_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA2
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   algobits  32 for a 32-bit algorithm, 64 for a 64-bit algorithm
 * @param   hashbits  Hash output size in bits
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `algobits` is invalid (neither 32 nor 64)
 * @throws  EINVAL  `hashbits` is invalid (neither 224, 256, 384, nor 512)
 * @throws  EINVAL  The combination of `algobits` and `hashbits` is invalid
 *                  (`hashbits` is 384 or 512 but `algobits` is 32)
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha2_hasher(struct libhashsum_hasher *this, unsigned algobits, size_t hashbits);

/**
 * Create an initialised state for Keccak-224
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_keccak_224_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for Keccak-256
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_keccak_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for Keccak-384
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_keccak_384_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for Keccak-512
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_keccak_512_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for Keccak
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   ratebits  Bitrate (in bits), 0 for automatic
 * @param   capbits   Capacity in bits, 0 for automatic
 * @param   hashbits  Hash output size in bits, 0 for automatic
 * @param   squeezes  The number of squeezes to performed, 0 for automatic (which is 1)
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  (`ratebits`, `capbits`, `hashbits`) is invalid
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits,
                                  size_t capbits, size_t hashbits, size_t squeezes);

/**
 * Create an initialised state for SHA3-224
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha3_224_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA3-256
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha3_256_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA3-384
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha3_384_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA3-512
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha3_512_hasher(struct libhashsum_hasher *this);

/**
 * Create an initialised state for SHA3
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is invalid (neither 224, 256, 384, nor 512)
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha3_hasher(struct libhashsum_hasher *this, size_t hashbits);

/**
 * Create an initialised state for SHAKE128
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits, if 0, 128 is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_shake128_hasher(struct libhashsum_hasher *this, size_t hashbits);

/**
 * Create an initialised state for SHAKE256
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits, if 0, 256 is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_shake256_hasher(struct libhashsum_hasher *this, size_t hashbits);

/**
 * Create an initialised state for SHAKE512
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits, if 0, 512 is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_shake512_hasher(struct libhashsum_hasher *this, size_t hashbits);

/**
 * Create an initialised state for SHAKE
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hcapbits  Half of the capacity, in bits (this is the
 *                    value added behind the function name)
 * @param   hashbits  Hash output size in bits, if 0, `hcapbits` is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hcapbits` is invalid (neither 128, 256, nor 512)
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_shake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits);

/**
 * Create an initialised state for RawSHAKE128
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits, if 0, 128 is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_rawshake128_hasher(struct libhashsum_hasher *this, size_t hashbits);

/**
 * Create an initialised state for RawSHAKE256
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits, if 0, 256 is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_rawshake256_hasher(struct libhashsum_hasher *this, size_t hashbits);

/**
 * Create an initialised state for RawSHAKE512
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits, if 0, 512 is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_rawshake512_hasher(struct libhashsum_hasher *this, size_t hashbits);

/**
 * Create an initialised state for RawSHAKE
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hcapbits  Half of the capacity, in bits (this is the
 *                    value added behind the function name)
 * @param   hashbits  Hash output size in bits, if 0, `hcapbits` is used
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hcapbits` is invalid (neither 128, 256, nor 512)
 * @throws  EINVAL  `hashbits` is too large
 * @throws  ENOSYS  Support was excluded at compile time
 * @throws  ENOMEM  Not enough memory available
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_rawshake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits);

/**
 * Create an initialised state for BLAKE224 (BLAKE, BLAKEs)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @param   salt  `NULL` (for all zeroes) or a 16-byte salt
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blake224_hasher(struct libhashsum_hasher *this, const void *salt);

/**
 * Create an initialised state for BLAKE256 (BLAKE, BLAKEs)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @param   salt  `NULL` (for all zeroes) or a 16-byte salt
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blake256_hasher(struct libhashsum_hasher *this, const void *salt);

/**
 * Create an initialised state for BLAKEs (BLAKE)
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits
 * @param   salt      `NULL` (for all zeroes) or a 16-byte salt
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is invalid (neither 224 nor 256)
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt);

/**
 * Create an initialised state for BLAKE384 (BLAKE, BLAKEb)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @param   salt  `NULL` (for all zeroes) or a 32-byte salt
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blake384_hasher(struct libhashsum_hasher *this, const void *salt);

/**
 * Create an initialised state for BLAKE512 (BLAKE, BLAKEb)
 * hashing and return hash functions and details
 * 
 * @param   this  The output parameter for the functions, details, and state
 * @param   salt  `NULL` (for all zeroes) or a 32-byte salt
 * @return        0 on success, -1 on failure
 * 
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blake512_hasher(struct libhashsum_hasher *this, const void *salt);

/**
 * Create an initialised state for BLAKEb (BLAKE)
 * hashing and return hash functions and details
 * 
 * @param   this      The output parameter for the functions, details, and state
 * @param   hashbits  Hash output size in bits
 * @param   salt      `NULL` (for all zeroes) or a 32-byte salt
 * @return            0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is invalid (neither 384 nor 512)
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt);

/**
 * Create an initialised state for BLAKE
 * hashing and return hash functions and details
 * 
 * @param   this       The output parameter for the functions, details, and state
 * @param   hashbits   Hash output size in bits
 * @param   salt       `NULL` (for all zeroes) or a salt
 * @param   saltbytes  The number of bytes in `salt` (ignored if `salt` is `NULL`),
 *                     shall be 16 for if `hashbits` is 224 or 256, and 32 if
 *                     `hashbits` is 384 or 512
 * @return             0 on success, -1 on failure
 * 
 * @throws  EINVAL  `hashbits` is invalid (neither 224, 256, 384, nor 512)
 * @throws  EINVAL  `salt` is not `NULL` but `saltbytes` does not match
 *                  the expected value for the input `hashbits`
 * @throws  ENOSYS  Support was excluded at compile time
 * 
 * @since  1.0
 */
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt, size_t saltbytes);


#endif