#include "gnunet_common.h"
#include "gnunet_scheduler_lib.h"
+#include <gcrypt.h>
/**
*/
#define GNUNET_CRYPTO_HASH_LENGTH (512/8)
+/**
+ * How many characters (without 0-terminator) are our ASCII-encoded
+ * public keys (ECDSA/EDDSA/ECDHE).
+ */
+#define GNUNET_CRYPTO_PKEY_ASCII_LENGTH 52
+
/**
* @brief 0-terminated ASCII encoding of a struct GNUNET_HashCode.
*/
struct GNUNET_CRYPTO_EddsaPublicKey
{
/**
- * Q consists of an x- and a y-value, each mod p (256 bits),
- * given here in affine coordinates.
- *
- * FIXME: this coordinate will be removed in the future (compressed point!).
- */
- unsigned char q_x[256 / 8];
-
- /**
- * Q consists of an x- and a y-value, each mod p (256 bits),
- * given here in affine coordinates.
+ * Q consists of an x- and a y-value, each mod p (256 bits), given
+ * here in affine coordinates and Ed25519 standard compact format.
*/
unsigned char q_y[256 / 8];
struct GNUNET_CRYPTO_EcdsaPublicKey
{
/**
- * Q consists of an x- and a y-value, each mod p (256 bits),
- * given here in affine coordinates.
- *
- * FIXME: this coordinate will be removed in the future (compressed point!).
- */
- unsigned char q_x[256 / 8];
-
- /**
- * Q consists of an x- and a y-value, each mod p (256 bits),
- * given here in affine coordinates.
+ * Q consists of an x- and a y-value, each mod p (256 bits), given
+ * here in affine coordinates and Ed25519 standard compact format.
*/
unsigned char q_y[256 / 8];
struct GNUNET_CRYPTO_EcdhePublicKey
{
/**
- * Q consists of an x- and a y-value, each mod p (256 bits),
- * given here in affine coordinates.
- */
- unsigned char q_x[256 / 8];
-
- /**
- * Q consists of an x- and a y-value, each mod p (256 bits),
- * given here in affine coordinates.
- *
- * FIXME: this coordinate will be removed in the future (compressed point!).
+ * Q consists of an x- and a y-value, each mod p (256 bits), given
+ * here in affine coordinates and Ed25519 standard compact format.
*/
unsigned char q_y[256 / 8];
-
};
};
+/**
+ * Size of paillier plain texts and public keys.
+ * Private keys and ciphertexts are twice this size.
+ */
+#define GNUNET_CRYPTO_PAILLIER_BITS 2048
+
+
+/**
+ * Paillier public key.
+ */
+struct GNUNET_CRYPTO_PaillierPublicKey
+{
+ /**
+ * N value.
+ */
+ unsigned char n[GNUNET_CRYPTO_PAILLIER_BITS / 8];
+};
+
+
+/**
+ * Paillier public key.
+ */
+struct GNUNET_CRYPTO_PaillierPrivateKey
+{
+ /**
+ * Lambda-component of the private key.
+ */
+ unsigned char lambda[GNUNET_CRYPTO_PAILLIER_BITS / 8];
+ /**
+ * Mu-component of the private key.
+ */
+ unsigned char mu[GNUNET_CRYPTO_PAILLIER_BITS / 8];
+};
+
+
+/**
+ * Paillier ciphertext.
+ */
+struct GNUNET_CRYPTO_PaillierCiphertext
+{
+ /**
+ * guaranteed minimum number of homomorphic operations with this ciphertext
+ */
+ int32_t remaining_ops GNUNET_PACKED;
+
+ /**
+ * The bits of the ciphertext.
+ */
+ unsigned char bits[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8];
+};
+
+
/* **************** Functions and Macros ************* */
/**
GNUNET_CRYPTO_crc32_n (const void *buf, size_t len);
+/**
+ * @ingroup crypto
+ * Fill block with a random values.
+ *
+ * @param mode desired quality of the random number
+ * @param buffer the buffer to fill
+ * @param length buffer length
+ */
+void
+GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length);
+
/**
* @ingroup crypto
* Produce a random value.
* Encrypt a block using a symmetric sessionkey.
*
* @param block the block to encrypt
- * @param len the size of the block
+ * @param size the size of the @a block
* @param sessionkey the key used to encrypt
* @param iv the initialization vector to use, use INITVALUE
* for streams.
* @return the size of the encrypted block, -1 for errors
*/
ssize_t
-GNUNET_CRYPTO_symmetric_encrypt (const void *block, size_t len,
+GNUNET_CRYPTO_symmetric_encrypt (const void *block, size_t size,
const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey,
const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv,
void *result);
struct GNUNET_CRYPTO_EddsaPrivateKey *
GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename);
+struct GNUNET_CONFIGURATION_Handle;
+
/**
* @ingroup crypto
GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
struct GNUNET_PeerIdentity *dst);
+/**
+ * Compare two Peer Identities.
+ *
+ * @param first first peer identity
+ * @param second second peer identity
+ * @return bigger than 0 if first > second,
+ * 0 if they are the same
+ * smaller than 0 if second > first
+ */
+int
+GNUNET_CRYPTO_cmp_peer_identity (const struct GNUNET_PeerIdentity *first,
+ const struct GNUNET_PeerIdentity *second);
+
/**
* @ingroup crypto
struct GNUNET_CRYPTO_EcdsaPublicKey *result);
+/**
+ * Output the given MPI value to the given buffer in network
+ * byte order. The MPI @a val may not be negative.
+ *
+ * @param buf where to output to
+ * @param size number of bytes in @a buf
+ * @param val value to write to @a buf
+ */
+void
+GNUNET_CRYPTO_mpi_print_unsigned (void *buf,
+ size_t size,
+ gcry_mpi_t val);
+
+
+/**
+ * Convert data buffer into MPI value.
+ * The buffer is interpreted as network
+ * byte order, unsigned integer.
+ *
+ * @param result where to store MPI value (allocated)
+ * @param data raw data (GCRYMPI_FMT_USG)
+ * @param size number of bytes in @a data
+ */
+void
+GNUNET_CRYPTO_mpi_scan_unsigned (gcry_mpi_t *result,
+ const void *data,
+ size_t size);
+
+
+/**
+ * Create a freshly generated paillier public key.
+ *
+ * @param[out] public_key Where to store the public key?
+ * @param[out] private_key Where to store the private key?
+ */
+void
+GNUNET_CRYPTO_paillier_create (struct GNUNET_CRYPTO_PaillierPublicKey *public_key,
+ struct GNUNET_CRYPTO_PaillierPrivateKey *private_key);
+
+
+/**
+ * Encrypt a plaintext with a paillier public key.
+ *
+ * @param public_key Public key to use.
+ * @param m Plaintext to encrypt.
+ * @param desired_ops How many homomorphic ops the caller intends to use
+ * @param[out] ciphertext Encrytion of @a plaintext with @a public_key.
+ * @return guaranteed number of supported homomorphic operations >= 1,
+ * or desired_ops, in case that is lower,
+ * or -1 if less than one homomorphic operation is possible
+ */
+int
+GNUNET_CRYPTO_paillier_encrypt (const struct GNUNET_CRYPTO_PaillierPublicKey *public_key,
+ const gcry_mpi_t m,
+ int desired_ops,
+ struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext);
+
+
+/**
+ * Decrypt a paillier ciphertext with a private key.
+ *
+ * @param private_key Private key to use for decryption.
+ * @param public_key Public key to use for decryption.
+ * @param ciphertext Ciphertext to decrypt.
+ * @param[out] m Decryption of @a ciphertext with @private_key.
+ */
+void
+GNUNET_CRYPTO_paillier_decrypt (const struct GNUNET_CRYPTO_PaillierPrivateKey *private_key,
+ const struct GNUNET_CRYPTO_PaillierPublicKey *public_key,
+ const struct GNUNET_CRYPTO_PaillierCiphertext *ciphertext,
+ gcry_mpi_t m);
+
+
+/**
+ * Compute a ciphertext that represents the sum of the plaintext in @a x1 and @a x2
+ *
+ * Note that this operation can only be done a finite number of times
+ * before an overflow occurs.
+ *
+ * @param public_key Public key to use for encryption.
+ * @param c1 Paillier cipher text.
+ * @param c2 Paillier cipher text.
+ * @param[out] result Result of the homomorphic operation.
+ * @return #GNUNET_OK if the result could be computed,
+ * #GNUNET_SYSERR if no more homomorphic operations are remaining.
+ */
+int
+GNUNET_CRYPTO_paillier_hom_add (const struct GNUNET_CRYPTO_PaillierPublicKey *public_key,
+ const struct GNUNET_CRYPTO_PaillierCiphertext *c1,
+ const struct GNUNET_CRYPTO_PaillierCiphertext *c2,
+ struct GNUNET_CRYPTO_PaillierCiphertext *result);
+
+
+/**
+ * Get the number of remaining supported homomorphic operations.
+ *
+ * @param c Paillier cipher text.
+ * @return the number of remaining homomorphic operations
+ */
+int
+GNUNET_CRYPTO_paillier_hom_get_remaining (const struct GNUNET_CRYPTO_PaillierCiphertext *c);
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif