
  /* Actual context.  */
  struct gcry_md_context *ctx;

  /* Buffer management.  */
  int  bufpos;
  int  bufsize;
  unsigned char buf[1];
} *gcry_md_hd_t;

/* Compatibility types, do not use them.  */
#ifndef GCRYPT_NO_DEPRECATED
typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED;
typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED;
#endif

/* Create a message digest object for algorithm ALGO.  FLAGS may be
   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
   given as 0 if the algorithms to be used are later set using
   gcry_md_enable.  */
gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);

/* Release the message digest object HD.  */
void gcry_md_close (gcry_md_hd_t hd);

/* Add the message digest algorithm ALGO to the digest object HD.  */
gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo);

/* Create a new digest object as an exact copy of the object HD.  */
gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);

/* Reset the digest object HD to its initial state.  */
void gcry_md_reset (gcry_md_hd_t hd);

/* Perform various operations on the digest object HD. */
gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd,
                          void *buffer, size_t buflen);

/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that
   it can update the digest values.  This is the actual hash
   function. */
void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);

/* Read out the final digest from HD return the digest value for
   algorithm ALGO. */
unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);

/* Read more output from algorithm ALGO to BUFFER of size LENGTH from
 * digest object HD. Algorithm needs to be 'expendable-output function'. */
gpg_error_t gcry_md_extract (gcry_md_hd_t hd, int algo, void *buffer,
                             size_t length);

/* Convenience function to calculate the hash from the data in BUFFER
   of size LENGTH using the algorithm ALGO avoiding the creation of a
   hash object.  The hash is returned in the caller provided buffer
   DIGEST which must be large enough to hold the digest of the given
   algorithm. */
void gcry_md_hash_buffer (int algo, void *digest,
                          const void *buffer, size_t length);

/* Convenience function to hash multiple buffers.  */
gpg_error_t gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
                                  const gcry_buffer_t *iov, int iovcnt);

/* Convenience function to hash multiple buffers.
   Algorithm can be 'expendable-output function'.  */
gpg_error_t gcry_md_hash_buffers_ext (int algo, unsigned int flags,
                                      void *digest, int digestlen,
                                      const gcry_buffer_t *iov, int iovcnt);

/* Retrieve the algorithm used with HD.  This does not work reliable
   if more than one algorithm is enabled in HD. */
int gcry_md_get_algo (gcry_md_hd_t hd);

/* Retrieve the length in bytes of the digest yielded by algorithm
   ALGO. */
unsigned int gcry_md_get_algo_dlen (int algo);

/* Return true if the the algorithm ALGO is enabled in the digest
   object A. */
int gcry_md_is_enabled (gcry_md_hd_t a, int algo);

/* Return true if the digest object A is allocated in "secure" memory. */
int gcry_md_is_secure (gcry_md_hd_t a);

/* Deprecated: Use gcry_md_is_enabled or gcry_md_is_secure.  */
gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
                          size_t *nbytes) _GCRY_ATTR_INTERNAL;

/* Retrieve various information about the algorithm ALGO.  */
gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer,
                               size_t *nbytes);

/* Map the digest algorithm id ALGO to a string representation of the
   algorithm name.  For unknown algorithms this function returns
   "?". */
const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;

/* Map the algorithm NAME to a digest algorithm Id.  Return 0 if
   the algorithm name is not known. */
int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;

/* For use with the HMAC feature, the set MAC key to the KEY of
   KEYLEN bytes. */
gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);

/* Start or stop debugging for digest handle HD; i.e. create a file
   named dbgmd-<n>.<suffix> while hashing.  If SUFFIX is NULL,
   debugging stops and the file will be closed. */
void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);


/* Update the hash(s) of H with the character C.  This is a buffered
   version of the gcry_md_write function. */
#define gcry_md_putc(h,c)  \
            do {                                          \
                gcry_md_hd_t h__ = (h);                   \
                if( (h__)->bufpos == (h__)->bufsize )     \
                    gcry_md_write( (h__), NULL, 0 );      \
                (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
            } while(0)

/* Finalize the digest calculation.  This is not really needed because
   gcry_md_read() does this implicitly. */
#define gcry_md_final(a) \
            gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)

/* Return 0 if the algorithm A is available for use. */
#define gcry_md_test_algo(a) \
            gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )

/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N
   must point to size_t variable with the available size of buffer B.
   After return it will receive the actual size of the returned
   OID. */
#define gcry_md_get_asnoid(a,b,n) \
            gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))

struct gcry_cshake_customization
{
  const void *n;
  unsigned int n_len;
  const void *s;
  unsigned int s_len;
};

