/* GNU Guix --- Functional package management for GNU
   Copyright © 2020 Maxime Devos <maxime.devos@student.kuleuven.be>

   This file is part of GNU Guix.

   GNU Guix is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or (at
   your option) any later version.

   GNU Guix is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>. */

/**
 * @brief Some DHT query encryption
 * @author Maxime Devos
 */

#ifndef GNUNET_REHASH_CRYPTO_H
#define GNUNET_REHASH_CRYPTO_H

#include "rehash_types.h"

#ifdef __cplusplus
extern "C"
{
#if 0
}
#endif
#endif

/**
 * Almost calculate the DHT query for finding a hash of type @a out_type
 * given the hash @a data of a certain @a in_type, except for the
 * final obfuscation step.
 *
 * The hash types do not have to be known to GNUnet-rehash.
 *
 * @param out_type hash type to try to find
 * @param in_type known hash type
 * @param data hash of type @a in_type
 * @param length length of @a data
 * @param query hash to use for query (output paramater)
 * @return #GNUNET_OK in case of success, #GNUNET_NO
 *  in case no DHT query is defined
 */
int
GNUNET_REHASH_cleartext_query_from_hash (
  enum GNUNET_REHASH_Hash_Type out_type,
  enum GNUNET_REHASH_Hash_Type in_type,
  const char *data,
  size_t data_size,
  struct GNUNET_HashCode *query);

/**
 * Calculate the DHT query for finding a hash of type @a out_type
 * given the hash @a data of a certain @a in_type
 *
 * The hash types do not have to be known to GNUnet-rehash.
 *
 * @param out_type hash type to try to find
 * @param in_type known hash type
 * @param data hash of type @a in_type
 * @param length length of @a data
 * @param query hash to use for query (output paramater)
 * @return #GNUNET_OK in case of success, #GNUNET_NO
 *  in case no DHT query is defined
 */
int
GNUNET_REHASH_obfuscated_query_from_hash (
  enum GNUNET_REHASH_Hash_Type out_type,
  enum GNUNET_REHASH_Hash_Type in_type,
  const char *data,
  size_t data_size,
  struct GNUNET_HashCode *query);

/**
 * Calculate how many bytes we will need to serialize
 * the hash_in -> hash_out mapping into data suitable
 * to put ito the DHT.
 *
 * @param out_size size of hash to find
 * @return the required size to serialize the serialized data,
 *   something strictly negative on error
 */
static inline ssize_t
GNUNET_REHASH_data_size_for_mapping (size_t out_size)
{
  if (out_size > 64)
    return -1;
  return out_size;
}

/**
 * Serialize the data to put into the DHT into a given destination buffer
 *
 * @param out_type hash type to search for
 * @param in_type hash type of hash to query with
 * @param out_data hash of type @a out_type
 * @param in_data hash of type @a in_type
 * @param out_size size of @a out_data buffer
 * @param in_size size of @a in_data buffer
 * @param dest where to write output
 * @param dest_size size of @a dest buffer
 * @return the size of the serialized data,
 *  -1 if data doesn't fit and in case
 *  of unreasonable inputs
 */
ssize_t
GNUNET_REHASH_data_for_mapping (
  enum GNUNET_REHASH_Hash_Type out_type,
  enum GNUNET_REHASH_Hash_Type in_type,
  const char *out_data,
  const char *in_data,
  size_t out_size,
  size_t in_size,
  char *dest,
  size_t dest_size);

/**
 * Deserialize data put into the DHT
 *
 * The hash type doesn't have to be known to GNUnet-rehash.
 * Corollary: output length may be bogus (even for
 * known hash types), even upon ‘successful’ returns.
 *
 * @param out_type hash type searched for
 * @param in_type  hash type searched with
 * @param in_data  hash of type @a in_type
 * @param in_size  size of @a in_data
 * @param dht_data data found in the DHT
 * @param dht_size size of @a dht_data and @a cleartext
 * @param cleartext (output parameter) hash found in the DHT
 * @returns #GNUNET_OK on success, #GNUNET_NO in case of some
 *  validation error
 */
int
GNUNET_REHASH_mapping_for_data (
  enum GNUNET_REHASH_Hash_Type out_type,
  enum GNUNET_REHASH_Hash_Type in_type,
  const char *in_data,
  size_t in_size,
  const char *dht_data,
  size_t dht_size,
  char *clearhash);

#if 0
{
#endif
#ifdef __cplusplus
}
#endif

#endif
