/* This file is part of GNUnet. Copyright (C) 2001-2023 GNUnet e.V. GNUnet is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GNUnet 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . SPDX-License-Identifier: AGPL3.0-or-later */ /** * @addtogroup libgnunetutil * Multi-function utilities library for GNUnet programs * @{ * * @file include/gnunet_crypto_lib.h * @brief cryptographic primitives for GNUnet * * @author Christian Grothoff * @author Krista Bennett * @author Gerd Knorr * @author Ioana Patrascu * @author Tzvetan Horozov * @author Jeffrey Burdges * * @defgroup crypto Crypto library: cryptographic operations * Provides cryptographic primitives. * * @see [Documentation](https://gnunet.org/crypto-api) * * @defgroup hash Crypto library: hash operations * Provides hashing and operations on hashes. * * @see [Documentation](https://gnunet.org/crypto-api) */ #if ! defined (__GNUNET_UTIL_LIB_H_INSIDE__) #error "Only can be included directly." #endif #ifndef GNUNET_CRYPTO_LIB_H #define GNUNET_CRYPTO_LIB_H #ifdef __cplusplus extern "C" { #if 0 /* keep Emacsens' auto-indent happy */ } #endif #endif #include #include /** * The identity of the host (wraps the signing key of the peer). */ struct GNUNET_PeerIdentity; #include /** * Maximum length of an ECC signature. * Note: round up to multiple of 8 minus 2 for alignment. */ #define GNUNET_CRYPTO_ECC_SIGNATURE_DATA_ENCODING_LENGTH 126 /** * Desired quality level for random numbers. * @ingroup crypto */ enum GNUNET_CRYPTO_Quality { /** * No good quality of the operation is needed (i.e., * random numbers can be pseudo-random). * @ingroup crypto */ GNUNET_CRYPTO_QUALITY_WEAK, /** * High-quality operations are desired. * @ingroup crypto */ GNUNET_CRYPTO_QUALITY_STRONG, /** * Randomness for IVs etc. is required. * @ingroup crypto */ GNUNET_CRYPTO_QUALITY_NONCE }; /** * @brief length of the sessionkey in bytes (256 BIT sessionkey) */ #define GNUNET_CRYPTO_AES_KEY_LENGTH (256 / 8) /** * Length of a hash value */ #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_HashAsciiEncoded { unsigned char encoding[104]; }; GNUNET_NETWORK_STRUCT_BEGIN /** * @brief header of what an ECC signature signs * this must be followed by "size - 8" bytes of * the actual signed data */ struct GNUNET_CRYPTO_EccSignaturePurpose { /** * How many bytes does this signature sign? * (including this purpose header); in network * byte order (!). */ uint32_t size GNUNET_PACKED; /** * What does this signature vouch for? This * must contain a GNUNET_SIGNATURE_PURPOSE_XXX * constant (from gnunet_signatures.h). In * network byte order! */ uint32_t purpose GNUNET_PACKED; }; /** * @brief an ECC signature using EdDSA. * See cr.yp.to/papers.html#ed25519 */ struct GNUNET_CRYPTO_EddsaSignature { /** * R value. */ unsigned char r[256 / 8]; /** * S value. */ unsigned char s[256 / 8]; }; /** * @brief an ECC signature using ECDSA */ struct GNUNET_CRYPTO_EcdsaSignature { /** * R value. */ unsigned char r[256 / 8]; /** * S value. */ unsigned char s[256 / 8]; }; /** * Public ECC key (always for curve Ed25519) encoded in a format * suitable for network transmission and EdDSA signatures. Refer * to section 5.1.3 of rfc8032, for a thorough explanation of how * this value maps to the x- and y-coordinates. */ struct GNUNET_CRYPTO_EddsaPublicKey { /** * Point Q consists of a y-value mod p (256 bits); the x-value is * always positive. The point is stored in Ed25519 standard * compact format. */ unsigned char q_y[256 / 8]; }; /** * Public ECC key (always for Curve25519) encoded in a format suitable * for network transmission and ECDSA signatures. */ struct GNUNET_CRYPTO_EcdsaPublicKey { /** * 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]; }; /** * The identity of the host (wraps the signing key of the peer). */ struct GNUNET_PeerIdentity { struct GNUNET_CRYPTO_EddsaPublicKey public_key; }; /** * Public ECC key (always for Curve25519) encoded in a format suitable * for network transmission and encryption (ECDH), * See http://cr.yp.to/ecdh.html */ struct GNUNET_CRYPTO_EcdhePublicKey { /** * 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]; }; /** * Private ECC key encoded for transmission. To be used only for ECDH * key exchange (ECDHE to be precise). */ struct GNUNET_CRYPTO_EcdhePrivateKey { /** * d is a value mod n, where n has at most 256 bits. */ unsigned char d[256 / 8]; }; /** * Private ECC key encoded for transmission. To be used only for ECDSA * signatures. */ struct GNUNET_CRYPTO_EcdsaPrivateKey { /** * d is a value mod n, where n has at most 256 bits. */ unsigned char d[256 / 8]; }; /** * Private ECC key encoded for transmission. To be used only for EdDSA * signatures. */ struct GNUNET_CRYPTO_EddsaPrivateKey { /** * d is a value mod n, where n has at most 256 bits. */ unsigned char d[256 / 8]; }; /** * Private ECC scalar encoded for transmission. To be used only for EdDSA * signatures. */ struct GNUNET_CRYPTO_EddsaPrivateScalar { /** * s is the expandedprivate 512-bit scalar of a private key. */ unsigned char s[512 / 8]; }; /** * Private ECC key material encoded for transmission. To be used only for * Edx25519 signatures. An initial key corresponds to data from the key * expansion and clamping in the EdDSA key generation. */ struct GNUNET_CRYPTO_Edx25519PrivateKey { /** * a is a value mod n, where n has at most 256 bits. It is the first half of * the seed-expansion of EdDSA and will be clamped. */ unsigned char a[256 / 8]; /** * b consists of 32 bytes which where originally the lower 32bytes of the key * expansion. Subsequent calls to derive_private will change this value, too. */ unsigned char b[256 / 8]; }; /** * Public ECC key (always for curve Ed25519) encoded in a format suitable for * network transmission and Edx25519 (same as EdDSA) signatures. Refer to * section 5.1.3 of rfc8032, for a thorough explanation of how this value maps * to the x- and y-coordinates. */ struct GNUNET_CRYPTO_Edx25519PublicKey { /** * Point Q consists of a y-value mod p (256 bits); the x-value is * always positive. The point is stored in Ed25519 standard * compact format. */ unsigned char q_y[256 / 8]; }; /** * @brief an ECC signature using Edx25519 (same as in EdDSA). */ struct GNUNET_CRYPTO_Edx25519Signature { /** * R value. */ unsigned char r[256 / 8]; /** * S value. */ unsigned char s[256 / 8]; }; /** * Elligator representative (always for Curve25519) */ struct GNUNET_CRYPTO_ElligatorRepresentative { /** * Represents an element of Curve25519 finite field. * Always smaller than 2 ^ 254 - 10 -> Needs to be serialized into a random-looking byte stream before transmission. */ unsigned char r[256 / 8]; }; /** * Key type for the generic public key union */ enum GNUNET_CRYPTO_KeyType { /** * The identity type. The value is the same as the * PKEY record type. */ GNUNET_PUBLIC_KEY_TYPE_ECDSA = 65536, /** * EDDSA identity. The value is the same as the EDKEY * record type. */ GNUNET_PUBLIC_KEY_TYPE_EDDSA = 65556 }; /** * A private key for an identity as per LSD0001. * Note that these types are NOT packed and MUST NOT be used in RPC * messages. Use the respective serialization functions. */ struct GNUNET_CRYPTO_PrivateKey { /** * Type of public key. * Defined by the GNS zone type value. * In NBO. */ uint32_t type; union { /** * An ECDSA identity key. */ struct GNUNET_CRYPTO_EcdsaPrivateKey ecdsa_key; /** * AN EdDSA identtiy key */ struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_key; }; }; /** * An identity key as per LSD0001. */ struct GNUNET_CRYPTO_PublicKey { /** * Type of public key. * Defined by the GNS zone type value. * In NBO. */ uint32_t type; union { /** * An ECDSA identity key. */ struct GNUNET_CRYPTO_EcdsaPublicKey ecdsa_key; /** * AN EdDSA identtiy key */ struct GNUNET_CRYPTO_EddsaPublicKey eddsa_key; }; }; /** * An identity signature as per LSD0001. */ struct GNUNET_CRYPTO_Signature { /** * Type of signature. * Defined by the GNS zone type value. * In NBO. */ uint32_t type; union { /** * An ECDSA signature */ struct GNUNET_CRYPTO_EcdsaSignature ecdsa_signature; /** * AN EdDSA signature */ struct GNUNET_CRYPTO_EddsaSignature eddsa_signature; }; }; /** * @brief type for session keys */ struct GNUNET_CRYPTO_SymmetricSessionKey { /** * Actual key for AES. */ unsigned char aes_key[GNUNET_CRYPTO_AES_KEY_LENGTH]; /** * Actual key for TwoFish. */ unsigned char twofish_key[GNUNET_CRYPTO_AES_KEY_LENGTH]; }; /** * Type of a nonce used for challenges. */ struct GNUNET_CRYPTO_ChallengeNonceP { /** * The value of the nonce. Note that this is NOT a hash. */ struct GNUNET_ShortHashCode value; }; GNUNET_NETWORK_STRUCT_END /** * @brief IV for sym cipher * * NOTE: must be smaller (!) in size than the * `struct GNUNET_HashCode`. */ struct GNUNET_CRYPTO_SymmetricInitializationVector { unsigned char aes_iv[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; unsigned char twofish_iv[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; }; /** * @brief type for (message) authentication keys */ struct GNUNET_CRYPTO_AuthKey { unsigned char key[GNUNET_CRYPTO_HASH_LENGTH]; }; /** * 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 private 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, * in network byte order (NBO). */ int32_t remaining_ops GNUNET_PACKED; /** * The bits of the ciphertext. */ unsigned char bits[GNUNET_CRYPTO_PAILLIER_BITS * 2 / 8]; }; /** * Curve25519 Scalar */ struct GNUNET_CRYPTO_Cs25519Scalar { /** * 32 byte scalar */ unsigned char d[crypto_core_ed25519_SCALARBYTES]; }; /** * Curve25519 point */ struct GNUNET_CRYPTO_Cs25519Point { /** * This is a point on the Curve25519. * The x coordinate can be restored using the y coordinate */ unsigned char y[crypto_core_ed25519_BYTES]; }; /** * The private information of an Schnorr key pair. */ struct GNUNET_CRYPTO_CsPrivateKey { struct GNUNET_CRYPTO_Cs25519Scalar scalar; }; /** * The public information of an Schnorr key pair. */ struct GNUNET_CRYPTO_CsPublicKey { struct GNUNET_CRYPTO_Cs25519Point point; }; /** * Secret used for blinding (alpha and beta). */ struct GNUNET_CRYPTO_CsBlindingSecret { struct GNUNET_CRYPTO_Cs25519Scalar alpha; struct GNUNET_CRYPTO_Cs25519Scalar beta; }; /** * the private r used in the signature */ struct GNUNET_CRYPTO_CsRSecret { struct GNUNET_CRYPTO_Cs25519Scalar scalar; }; /** * the public R (derived from r) used in c */ struct GNUNET_CRYPTO_CsRPublic { struct GNUNET_CRYPTO_Cs25519Point point; }; /** * Schnorr c to be signed */ struct GNUNET_CRYPTO_CsC { struct GNUNET_CRYPTO_Cs25519Scalar scalar; }; /** * s in the signature */ struct GNUNET_CRYPTO_CsS { struct GNUNET_CRYPTO_Cs25519Scalar scalar; }; /** * blinded s in the signature */ struct GNUNET_CRYPTO_CsBlindS { struct GNUNET_CRYPTO_Cs25519Scalar scalar; }; /** * CS Signtature containing scalar s and point R */ struct GNUNET_CRYPTO_CsSignature { /** * Schnorr signatures are composed of a scalar s and a curve point */ struct GNUNET_CRYPTO_CsS s_scalar; /** * Curve point of the Schnorr signature. */ struct GNUNET_CRYPTO_CsRPublic r_point; }; /** * Nonce for the session, picked by client, * shared with the signer. */ struct GNUNET_CRYPTO_CsSessionNonce { /*a nonce*/ unsigned char snonce[256 / 8]; }; /** * Nonce for computing blinding factors. Not * shared with the signer. */ struct GNUNET_CRYPTO_CsBlindingNonce { /*a nonce*/ unsigned char bnonce[256 / 8]; }; /* **************** Functions and Macros ************* */ /** * @ingroup crypto * Seed a weak random generator. Only #GNUNET_CRYPTO_QUALITY_WEAK-mode generator * can be seeded. * * @param seed the seed to use */ void GNUNET_CRYPTO_seed_weak_random (int32_t seed); /** * @ingroup hash * Calculate the checksum of a buffer in one step. * * @param buf buffer to calculate CRC over * @param len number of bytes in @a buf * @return crc8 value */ uint8_t GNUNET_CRYPTO_crc8_n (const void *buf, size_t len); /** * Perform an incremental step in a CRC16 (for TCP/IP) calculation. * * @param sum current sum, initially 0 * @param buf buffer to calculate CRC over (must be 16-bit aligned) * @param len number of bytes in @a buf, must be multiple of 2 * @return updated crc sum (must be subjected to #GNUNET_CRYPTO_crc16_finish to get actual crc16) */ uint32_t GNUNET_CRYPTO_crc16_step (uint32_t sum, const void *buf, size_t len); /** * Convert results from GNUNET_CRYPTO_crc16_step to final crc16. * * @param sum cumulative sum * @return crc16 value */ uint16_t GNUNET_CRYPTO_crc16_finish (uint32_t sum); /** * @ingroup hash * Calculate the checksum of a buffer in one step. * * @param buf buffer to calculate CRC over (must be 16-bit aligned) * @param len number of bytes in @a buf, must be multiple of 2 * @return crc16 value */ uint16_t GNUNET_CRYPTO_crc16_n (const void *buf, size_t len); /** * @ingroup hash * Compute the CRC32 checksum for the first len * bytes of the buffer. * * @param buf the data over which we're taking the CRC * @param len the length of the buffer @a buf in bytes * @return the resulting CRC32 checksum */ int32_t GNUNET_CRYPTO_crc32_n (const void *buf, size_t len); /** * @ingroup crypto * Zero out @a buffer, securely against compiler optimizations. * Used to delete key material. * * @param buffer the buffer to zap * @param length buffer length */ void GNUNET_CRYPTO_zero_keys (void *buffer, size_t length); /** * @ingroup crypto * Fill block with a random values. * * @param mode desired quality of the random number * @param[out] 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 * Fill UUID with a timeflake pseudo-random value. Note that * timeflakes use only 80 bits of randomness and 48 bits * to encode a timestamp in milliseconds. So what we return * here is not a completely random number. * * @param mode desired quality of the random number * @param[out] uuid the value to fill */ void GNUNET_CRYPTO_random_timeflake (enum GNUNET_CRYPTO_Quality mode, struct GNUNET_Uuid *uuid); /** * @ingroup crypto * Produce a random value. * * @param mode desired quality of the random number * @param i the upper limit (exclusive) for the random number * @return a random value in the interval [0,@a i) (exclusive). */ uint32_t GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode, uint32_t i); /** * @ingroup crypto * Generate a random unsigned 64-bit value. * * @param mode desired quality of the random number * @param max value returned will be in range [0,@a max) (exclusive) * @return random 64-bit number */ uint64_t GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max); /** * @ingroup crypto * Get an array with a random permutation of the * numbers 0...n-1. * @param mode #GNUNET_CRYPTO_QUALITY_STRONG if the strong (but expensive) PRNG should be used, * #GNUNET_CRYPTO_QUALITY_WEAK or #GNUNET_CRYPTO_QUALITY_NONCE otherwise * @param n the size of the array * @return the permutation array (allocated from heap) */ unsigned int * GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n); /** * @ingroup crypto * Create a new random session key. * * @param key key to initialize */ void GNUNET_CRYPTO_symmetric_create_session_key ( struct GNUNET_CRYPTO_SymmetricSessionKey *key); /** * @ingroup crypto * Encrypt a block using a symmetric sessionkey. * * @param block the block to encrypt * @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 size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result); /** * @ingroup crypto * Decrypt a given block using a symmetric sessionkey. * * @param block the data to decrypt, encoded as returned by encrypt * @param size how big is the block? * @param sessionkey the key used to decrypt * @param iv the initialization vector to use * @param result address to store the result at * @return -1 on failure, size of decrypted block on success */ ssize_t GNUNET_CRYPTO_symmetric_decrypt ( const void *block, size_t size, const struct GNUNET_CRYPTO_SymmetricSessionKey *sessionkey, const struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, void *result); /** * @ingroup crypto * @brief Derive an IV * @param iv initialization vector * @param skey session key * @param salt salt for the derivation * @param salt_len size of the @a salt * @param ... pairs of void * & size_t for context chunks, terminated by NULL */ void GNUNET_CRYPTO_symmetric_derive_iv ( struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len, ...); /** * @brief Derive an IV * @param iv initialization vector * @param skey session key * @param salt salt for the derivation * @param salt_len size of the @a salt * @param argp pairs of void * & size_t for context chunks, terminated by NULL */ void GNUNET_CRYPTO_symmetric_derive_iv_v ( struct GNUNET_CRYPTO_SymmetricInitializationVector *iv, const struct GNUNET_CRYPTO_SymmetricSessionKey *skey, const void *salt, size_t salt_len, va_list argp); /** * @ingroup hash * Convert hash to ASCII encoding. * @param block the hash code * @param result where to store the encoding (struct GNUNET_CRYPTO_HashAsciiEncoded can be * safely cast to char*, a '\\0' termination is set). */ void GNUNET_CRYPTO_hash_to_enc (const struct GNUNET_HashCode *block, struct GNUNET_CRYPTO_HashAsciiEncoded *result); /** * @ingroup hash * Convert ASCII encoding back to a 'struct GNUNET_HashCode' * * @param enc the encoding * @param enclen number of characters in @a enc (without 0-terminator, which can be missing) * @param result where to store the hash code * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen, struct GNUNET_HashCode *result); /** * @ingroup hash * Convert ASCII encoding back to `struct GNUNET_HashCode` * * @param enc the encoding * @param result where to store the hash code * @return #GNUNET_OK on success, #GNUNET_SYSERR if result has the wrong encoding */ #define GNUNET_CRYPTO_hash_from_string(enc, result) \ GNUNET_CRYPTO_hash_from_string2 (enc, strlen (enc), result) /** * @ingroup hash * * Compute the distance between 2 hashcodes. The * computation must be fast, not involve @a a[0] or @a a[4] (they're used * elsewhere), and be somewhat consistent. And of course, the result * should be a positive number. * * @param a some hash code * @param b some hash code * @return number between 0 and UINT32_MAX */ uint32_t GNUNET_CRYPTO_hash_distance_u32 (const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b); /** * @ingroup hash * Compute hash of a given block. * * @param block the data to hash * @param size size of the @a block * @param ret pointer to where to write the hashcode */ void GNUNET_CRYPTO_hash (const void *block, size_t size, struct GNUNET_HashCode *ret); /** * Value for a salt for #GNUNET_CRYPTO_pow_hash(). */ struct GNUNET_CRYPTO_PowSalt { char salt[crypto_pwhash_argon2id_SALTBYTES]; }; /** * Calculate the 'proof-of-work' hash (an expensive hash). * * @param salt salt for the hash. Must be crypto_pwhash_argon2id_SALTBYTES long. * @param buf data to hash * @param buf_len number of bytes in @a buf * @param result where to write the resulting hash */ void GNUNET_CRYPTO_pow_hash (const struct GNUNET_CRYPTO_PowSalt *salt, const void *buf, size_t buf_len, struct GNUNET_HashCode *result); /** * Context for cumulative hashing. */ struct GNUNET_HashContext; /** * Start incremental hashing operation. * * @return context for incremental hash computation */ struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start (void); /** * Make a copy of the hash computation. * * @param hc hash context to use (to continue hashing independently) * @return copy of @a hc */ struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_copy (const struct GNUNET_HashContext *hc); /** * Add data to be hashed. * * @param hc cumulative hash context * @param buf data to add * @param size number of bytes in @a buf */ void GNUNET_CRYPTO_hash_context_read (struct GNUNET_HashContext *hc, const void *buf, size_t size); /** * Finish the hash computation. * * @param hc hash context to use, is freed in the process * @param r_hash where to write the latest / final hash code */ void GNUNET_CRYPTO_hash_context_finish (struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash); /** * Abort hashing, do not bother calculating final result. * * @param hc hash context to destroy */ void GNUNET_CRYPTO_hash_context_abort (struct GNUNET_HashContext *hc); /** * Calculate HMAC of a message (RFC 2104) * TODO: Shouldn't this be the standard hmac function and * the above be renamed? * * @param key secret key * @param key_len secret key length * @param plaintext input plaintext * @param plaintext_len length of @a plaintext * @param hmac where to store the hmac */ void GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac); /** * @ingroup hash * Calculate HMAC of a message (RFC 2104) * * @param key secret key * @param plaintext input plaintext * @param plaintext_len length of @a plaintext * @param hmac where to store the hmac */ void GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, struct GNUNET_HashCode *hmac); /** * Function called once the hash computation over the * specified file has completed. * * @param cls closure * @param res resulting hash, NULL on error */ typedef void (*GNUNET_CRYPTO_HashCompletedCallback) ( void *cls, const struct GNUNET_HashCode *res); /** * Handle to file hashing operation. */ struct GNUNET_CRYPTO_FileHashContext; /** * @ingroup hash * Compute the hash of an entire file. * * @param priority scheduling priority to use * @param filename name of file to hash * @param blocksize number of bytes to process in one task * @param callback function to call upon completion * @param callback_cls closure for @a callback * @return NULL on (immediate) error */ struct GNUNET_CRYPTO_FileHashContext * GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority, const char *filename, size_t blocksize, GNUNET_CRYPTO_HashCompletedCallback callback, void *callback_cls); /** * Cancel a file hashing operation. * * @param fhc operation to cancel (callback must not yet have been invoked) */ void GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc); /** * @ingroup hash * Create a random hash code. * * @param mode desired quality level * @param result hash code that is randomized */ void GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, struct GNUNET_HashCode *result); /** * @ingroup hash * compute @a result = @a b - @a a * * @param a some hash code * @param b some hash code * @param result set to @a b - @a a */ void GNUNET_CRYPTO_hash_difference (const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result); /** * @ingroup hash * compute @a result = @a a + @a delta * * @param a some hash code * @param delta some hash code * @param result set to @a a + @a delta */ void GNUNET_CRYPTO_hash_sum (const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *delta, struct GNUNET_HashCode *result); /** * @ingroup hash * compute result = a ^ b * * @param a some hash code * @param b some hash code * @param result set to @a a ^ @a b */ void GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode *a, const struct GNUNET_HashCode *b, struct GNUNET_HashCode *result); /** * Count the number of leading 0 bits in @a h. * * @param h a hash * @return number of leading 0 bits in @a h */ unsigned int GNUNET_CRYPTO_hash_count_leading_zeros (const struct GNUNET_HashCode *h); /** * Count the number of tailing 0 bits in @a h. * * @param h a hash * @return number of tailing 0 bits in @a h */ unsigned int GNUNET_CRYPTO_hash_count_tailing_zeros (const struct GNUNET_HashCode *h); /** * @ingroup hash * Convert a hashcode into a key. * * @param hc hash code that serves to generate the key * @param skey set to a valid session key * @param iv set to a valid initialization vector */ void GNUNET_CRYPTO_hash_to_aes_key ( const struct GNUNET_HashCode *hc, struct GNUNET_CRYPTO_SymmetricSessionKey *skey, struct GNUNET_CRYPTO_SymmetricInitializationVector *iv); /** * @ingroup hash * Compare function for HashCodes, producing a total ordering * of all hashcodes. * * @param h1 some hash code * @param h2 some hash code * @return 1 if @a h1 > @a h2, -1 if @a h1 < @a h2 and 0 if @a h1 == @a h2. */ int GNUNET_CRYPTO_hash_cmp (const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2); /** * @ingroup hash * Find out which of the two GNUNET_CRYPTO_hash codes is closer to target * in the XOR metric (Kademlia). * * @param h1 some hash code * @param h2 some hash code * @param target some hash code * @return -1 if @a h1 is closer, 1 if @a h2 is closer and 0 if @a h1== @a h2. */ int GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2, const struct GNUNET_HashCode *target); /** * @ingroup hash * @brief Derive an authentication key * @param key authentication key * @param rkey root key * @param salt salt * @param salt_len size of the salt * @param argp pair of void * & size_t for context chunks, terminated by NULL */ void GNUNET_CRYPTO_hmac_derive_key_v ( struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len, va_list argp); /** * @ingroup hash * @brief Derive an authentication key * @param key authentication key * @param rkey root key * @param salt salt * @param salt_len size of the salt * @param ... pair of void * & size_t for context chunks, terminated by NULL */ void GNUNET_CRYPTO_hmac_derive_key ( struct GNUNET_CRYPTO_AuthKey *key, const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey, const void *salt, size_t salt_len, ...); /** * @ingroup hash * @brief Derive key * @param result buffer for the derived key, allocated by caller * @param out_len desired length of the derived key * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... * @param xts salt * @param xts_len length of @a xts * @param skm source key material * @param skm_len length of @a skm * @param ... pair of void * & size_t for context chunks, terminated by NULL * @return #GNUNET_YES on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf (void *result, size_t out_len, int xtr_algo, int prf_algo, const void *xts, size_t xts_len, const void *skm, size_t skm_len, ...); /** * @ingroup hash * @brief Derive key * @param result buffer for the derived key, allocated by caller * @param out_len desired length of the derived key * @param xtr_algo hash algorithm for the extraction phase, GCRY_MD_... * @param prf_algo hash algorithm for the expansion phase, GCRY_MD_... * @param xts salt * @param xts_len length of @a xts * @param skm source key material * @param skm_len length of @a skm * @param argp va_list of void * & size_t pairs for context chunks * @return #GNUNET_YES on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_hkdf_v (void *result, size_t out_len, int xtr_algo, int prf_algo, const void *xts, size_t xts_len, const void *skm, size_t skm_len, va_list argp); /** * @brief Derive key * @param result buffer for the derived key, allocated by caller * @param out_len desired length of the derived key * @param xts salt * @param xts_len length of @a xts * @param skm source key material * @param skm_len length of @a skm * @param argp va_list of void * & size_t pairs for context chunks * @return #GNUNET_YES on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf_v (void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len, va_list argp); /** * Deterministically generate a pseudo-random number uniformly from the * integers modulo a libgcrypt mpi. * * @param[out] r MPI value set to the FDH * @param n MPI to work modulo * @param xts salt * @param xts_len length of @a xts * @param skm source key material * @param skm_len length of @a skm * @param ctx context string */ void GNUNET_CRYPTO_kdf_mod_mpi (gcry_mpi_t *r, gcry_mpi_t n, const void *xts, size_t xts_len, const void *skm, size_t skm_len, const char *ctx); /** * @ingroup hash * @brief Derive key * @param result buffer for the derived key, allocated by caller * @param out_len desired length of the derived key * @param xts salt * @param xts_len length of @a xts * @param skm source key material * @param skm_len length of @a skm * @param ... void * & size_t pairs for context chunks * @return #GNUNET_YES on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_kdf (void *result, size_t out_len, const void *xts, size_t xts_len, const void *skm, size_t skm_len, ...); /** * @ingroup crypto * Extract the public key for the given private key. * * @param priv the private key * @param pub where to write the public key */ void GNUNET_CRYPTO_ecdsa_key_get_public ( const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub); /** * @ingroup crypto * Extract the public key for the given private key. * * @param priv the private key * @param pub where to write the public key */ void GNUNET_CRYPTO_eddsa_key_get_public ( const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub); /** * @ingroup crypto * Extract the public key for the given private key. * * @param priv the private key * @param pub where to write the public key */ void GNUNET_CRYPTO_edx25519_key_get_public ( const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, struct GNUNET_CRYPTO_Edx25519PublicKey *pub); /** * @ingroup crypto * Extract the public key for the given private key. * * @param priv the private key * @param pub where to write the public key */ void GNUNET_CRYPTO_ecdhe_key_get_public ( const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub); /** * Convert a public key to a string. * * @param pub key to convert * @return string representing @a pub */ char * GNUNET_CRYPTO_ecdsa_public_key_to_string ( const struct GNUNET_CRYPTO_EcdsaPublicKey *pub); /** * Convert a private key to a string. * * @param priv key to convert * @return string representing @a priv */ char * GNUNET_CRYPTO_ecdsa_private_key_to_string ( const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv); /** * Convert a private key to a string. * * @param priv key to convert * @return string representing @a pub */ char * GNUNET_CRYPTO_eddsa_private_key_to_string ( const struct GNUNET_CRYPTO_EddsaPrivateKey *priv); /** * Convert a public key to a string. * * @param pub key to convert * @return string representing @a pub */ char * GNUNET_CRYPTO_eddsa_public_key_to_string ( const struct GNUNET_CRYPTO_EddsaPublicKey *pub); /** * Convert a string representing a public key to a public key. * * @param enc encoded public key * @param enclen number of bytes in @a enc (without 0-terminator) * @param pub where to store the public key * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_public_key_from_string ( const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub); /** * Convert a string representing a private key to a private key. * * @param enc encoded public key * @param enclen number of bytes in @a enc (without 0-terminator) * @param priv where to store the private key * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_private_key_from_string ( const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPrivateKey *priv); /** * Convert a string representing a public key to a public key. * * @param enc encoded public key * @param enclen number of bytes in @a enc (without 0-terminator) * @param pub where to store the public key * @return #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string ( const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub); /** * @ingroup crypto * @brief Create a new private key by reading it from a file. * * If the files does not exist and @a do_create is set, creates a new key and * write it to the file. * * If the contents of the file are invalid, an error is returned. * * @param filename name of file to use to store the key * @param do_create should a file be created? * @param[out] pkey set to the private key from @a filename on success * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but * we found an existing file, #GNUNET_SYSERR on failure */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_key_from_file (const char *filename, int do_create, struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey); /** * @ingroup crypto * @brief Create a new private key by reading it from a file. * * If the files does not exist and @a do_create is set, creates a new key and * write it to the file. * * If the contents of the file are invalid, an error is returned. * * @param filename name of file to use to store the key * @param do_create should a file be created? * @param[out] pkey set to the private key from @a filename on success * @return #GNUNET_OK on success, #GNUNET_NO if @a do_create was set but * we found an existing file, #GNUNET_SYSERR on failure */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_key_from_file (const char *filename, int do_create, struct GNUNET_CRYPTO_EddsaPrivateKey *pkey); /** * Forward declaration to simplify #include-structure. */ struct GNUNET_CONFIGURATION_Handle; /** * @ingroup crypto * Create a new private key by reading our peer's key from * the file specified in the configuration. * * @param cfg the configuration to use * @return new private key, NULL on error (for example, * permission denied); free using #GNUNET_free */ struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_create_from_configuration ( const struct GNUNET_CONFIGURATION_Handle *cfg); /** * @ingroup crypto * Create a new private key. * * @param[out] pk private key to initialize */ void GNUNET_CRYPTO_ecdsa_key_create (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk); /** * @ingroup crypto * Create a new private key. * * @param[out] pk private key to initialize */ void GNUNET_CRYPTO_eddsa_key_create (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); /** * @ingroup crypto * Create a new private key. * * @param[out] pk private key to initialize */ void GNUNET_CRYPTO_edx25519_key_create (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); /** * @ingroup crypto * Create a new private key for Edx25519 from a given seed. After expanding * the seed, the first half of the key will be clamped according to EdDSA. * * @param seed seed input * @param seedsize size of the seed in bytes * @param[out] pk private key to initialize */ void GNUNET_CRYPTO_edx25519_key_create_from_seed ( const void *seed, size_t seedsize, struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); /** * @ingroup crypto * Create a new private key. Clear with #GNUNET_CRYPTO_ecdhe_key_clear(). * This is X25519 DH (RFC 7748 Section 5) and corresponds to * X25519(a,9). * See #GNUNET_CRYPTO_ecc_ecdh for the DH function. * * @param[out] pk set to fresh private key; */ void GNUNET_CRYPTO_ecdhe_key_create (struct GNUNET_CRYPTO_EcdhePrivateKey *pk); /** * @ingroup crypto * Clear memory that was used to store a private key. * * @param pk location of the key */ void GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk); /** * @ingroup crypto * Clear memory that was used to store a private key. * * @param pk location of the key */ void GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk); /** * @ingroup crypto * Clear memory that was used to store a private key. * * @param pk location of the key */ void GNUNET_CRYPTO_edx25519_key_clear (struct GNUNET_CRYPTO_Edx25519PrivateKey *pk); /** * @ingroup crypto * Clear memory that was used to store a private key. * * @param pk location of the key */ void GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk); /** * @ingroup crypto * Get the shared private key we use for anonymous users. * * @return "anonymous" private key; do not free */ const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_get_anonymous (void); /** * @ingroup crypto * Setup a hostkey file for a peer given the name of the * configuration file (!). This function is used so that * at a later point code can be certain that reading a * hostkey is fast (for example in time-dependent testcases). * * @param cfg_name name of the configuration file to use */ void GNUNET_CRYPTO_eddsa_setup_hostkey (const char *cfg_name); /** * @ingroup crypto * Retrieve the identity of the host's peer. * * @param cfg configuration to use * @param dst pointer to where to write the peer identity * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity * could not be retrieved */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_PeerIdentity *dst); /** * @ingroup crypto * Sign a given block with a specific purpose using the host's peer identity. * * @param cfg configuration to use * @param purpose what to sign (size, purpose) * @param sig where to write the signature * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity * could not be retrieved */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_sign_by_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig); /** * @ingroup crypto * Verify a given signature with a peer's identity. * * @param purpose what is the purpose that the signature should have? * @param validate block to validate (size, purpose, data) * @param sig signature that is being validated * @param identity the peer's identity to verify * @return #GNUNET_OK if ok, #GNUNET_SYSERR if invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_verify_peer_identity (uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_PeerIdentity *identity); /** * Internal structure used to cache pre-calculated values for DLOG calculation. */ struct GNUNET_CRYPTO_EccDlogContext; /** * Point on a curve (always for Curve25519) encoded in a format suitable * for network transmission (ECDH), see http://cr.yp.to/ecdh.html. */ struct GNUNET_CRYPTO_EccPoint { /** * 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 v[256 / 8]; }; /** * A ECC scalar for use in point multiplications */ struct GNUNET_CRYPTO_EccScalar { unsigned char v[256 / 8]; }; /** * Do pre-calculation for ECC discrete logarithm for small factors. * * @param max maximum value the factor can be * @param mem memory to use (should be smaller than @a max), must not be zero. * @return NULL on error */ struct GNUNET_CRYPTO_EccDlogContext * GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, unsigned int mem); /** * Calculate ECC discrete logarithm for small factors. * Opposite of #GNUNET_CRYPTO_ecc_dexp(). * * @param edc precalculated values, determine range of factors * @param input point on the curve to factor * @return INT_MAX if dlog failed, otherwise the factor */ int GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, const struct GNUNET_CRYPTO_EccPoint *input); /** * Multiply the generator g of the elliptic curve by @a val * to obtain the point on the curve representing @a val. * Afterwards, point addition will correspond to integer * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to * convert a point back to an integer (as long as the * integer is smaller than the MAX of the @a edc context). * * @param val value to encode into a point * @param r where to write the point (must be allocated) */ void GNUNET_CRYPTO_ecc_dexp (int val, struct GNUNET_CRYPTO_EccPoint*r); /** * Multiply the generator g of the elliptic curve by @a val * to obtain the point on the curve representing @a val. * * @param val (positive) value to encode into a point * @param r where to write the point (must be allocated) * @return #GNUNET_OK on success. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_dexp_mpi (const struct GNUNET_CRYPTO_EccScalar *val, struct GNUNET_CRYPTO_EccPoint *r); /** * Multiply the point @a p on the elliptic curve by @a val. * * @param p point to multiply * @param val (positive) value to encode into a point * @param r where to write the point (must be allocated) * @return #GNUNET_OK on success. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_pmul_mpi (const struct GNUNET_CRYPTO_EccPoint *p, const struct GNUNET_CRYPTO_EccScalar *val, struct GNUNET_CRYPTO_EccPoint *r); /** * Add two points on the elliptic curve. * * @param a some value * @param b some value * @param r where to write the point (must be allocated) * @return #GNUNET_OK on success. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_add (const struct GNUNET_CRYPTO_EccPoint *a, const struct GNUNET_CRYPTO_EccPoint *b, struct GNUNET_CRYPTO_EccPoint *r); /** * Obtain a random point on the curve and its * additive inverse. * * @param[out] r set to a random point on the curve * @param[out] r_inv set to the additive inverse of @a r * @return #GNUNET_OK on success. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccPoint *r, struct GNUNET_CRYPTO_EccPoint *r_inv); /** * Obtain a random scalar for point multiplication on the curve and * its additive inverse. * * @param[out] r set to a random scalar on the curve * @param[out] r_neg set to the negation of @a */ void GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccScalar *r, struct GNUNET_CRYPTO_EccScalar *r_neg); /** * Generate a random value mod n. * * @param[out] r random value mod n. */ void GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccScalar*r); /** * Release precalculated values. * * @param dlc dlog context */ void GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *dlc); /** * Create a scalar from int value. * * @param val the int value * @param[out] r where to write the salar */ void GNUNET_CRYPTO_ecc_scalar_from_int (int64_t val, struct GNUNET_CRYPTO_EccScalar *r); /** * @ingroup crypto * Derive key material from a public and a private ECC key. * This is X25519 DH (RFC 7748 Section 5) and corresponds to * H(X25519(b,X25519(a,9))) where b := priv, pub := X25519(a,9), * and a := #GNUNET_CRYPTO_ecdhe_key_create(). * * @param priv private key to use for the ECDH (x) * @param pub public key to use for the ECDH (yG) * @param key_material where to write the key material (xyG) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Derive key material from a ECDH public key and a private EdDSA key. * Dual to #GNUNET_CRRYPTO_ecdh_eddsa. * This uses the Ed25519 private seed as X25519 seed. * As such, this also is a X25519 DH (see #GNUNET_CRYPTO_ecc_ecdh). * NOTE: Whenever you can get away with it, use separate key pairs * for signing and encryption (DH)! * * @param priv private key from EdDSA to use for the ECDH (x) * @param pub public key to use for the ECDH (yG) * @param key_material where to write the key material H(h(x)yG) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Decapsulate a key for a private EdDSA key. * Dual to #GNUNET_CRRYPTO_eddsa_kem_encaps. * * @param priv private key from EdDSA to use for the ECDH (x) * @param c the encapsulated key * @param key_material where to write the key material H(h(x)yG) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_decaps (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Encapsulate key material for a EdDSA public key. * Dual to #GNUNET_CRRYPTO_eddsa_kem_decaps. * * @param priv private key to use for the ECDH (y) * @param c public key from EdDSA to use for the ECDH (X=h(x)G) * @param key_material where to write the key material H(yX)=H(h(x)yG) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_kem_encaps (const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *c, struct GNUNET_HashCode *key_material); /** * This is the encapsulated key of our FO-KEM. */ struct GNUNET_CRYPTO_FoKemC { /* The output of the FO-OWTF F(x) */ struct GNUNET_HashCode y; /* The ephemeral public key from the DH in the KEM */ struct GNUNET_CRYPTO_EcdhePublicKey pub; }; /** * @ingroup crypto * Encapsulate key material using a CCA-secure KEM. * The KEM is using a OWTF with image oracle constructed from * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_decaps. * * @param pub public key to encapsulated for * @param[out] c the encapsulation * @param[out] key_material the encapsulated key * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_fo_kem_encaps ( const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Decapsulate key material using a CCA-secure KEM. * The KEM is using a OWTF with image oracle constructed from * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_encaps. * * @param priv private key this encapsulation is for * @param c the encapsulation * @param[out] key_material the encapsulated key * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_fo_kem_decaps (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Encapsulate key material using a CCA-secure KEM. * The KEM is using a OWTF with image oracle constructed from * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_decaps. * * @param pub public key to encapsulated for * @param[out] c the encapsulation * @param[out] key_material the encapsulated key * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_fo_kem_encaps (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Decapsulate key material using a CCA-secure KEM. * The KEM is using a OWTF with image oracle constructed from * a Fujusaki-Okamoto transformation using ElGamal (DH plus XOR OTP). * Dual to #GNUNET_CRRYPTO_eddsa_fo_kem_encaps. * * @param priv private key this encapsulation is for * @param c the encapsulation * @param[out] key_material the encapsulated key * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_fo_kem_decaps (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_FoKemC *c, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Derive key material from a ECDH public key and a private ECDSA key. * Dual to #GNUNET_CRRYPTO_ecdh_ecdsa. * * @param priv private key from ECDSA to use for the ECDH (x) * @param pub public key to use for the ECDH (yG) * @param key_material where to write the key material H(h(x)yG) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Derive key material from a EdDSA public key and a private ECDH key. * Dual to #GNUNET_CRRYPTO_eddsa_ecdh. * This converts the Edwards25519 public key @a pub to a Curve25519 * public key before computing a X25519 DH (see #GNUNET_CRYPTO_ecc_ecdh). * NOTE: Whenever you can get away with it, use separate key pairs * for signing and encryption (DH)! * * @param priv private key to use for the ECDH (y) * @param pub public key from EdDSA to use for the ECDH (X=h(x)G) * @param key_material where to write the key material H(yX)=H(h(x)yG) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * Derive key material from a EcDSA public key and a private ECDH key. * Dual to #GNUNET_CRRYPTO_ecdsa_ecdh. * * @param priv private key to use for the ECDH (y) * @param pub public key from ECDSA to use for the ECDH (X=h(x)G) * @param key_material where to write the key material H(yX)=H(h(x)yG) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_HashCode *key_material); /** * @ingroup crypto * @brief EdDSA sign a given block. * * The @a purpose data is the beginning of the data of which the signature is * to be created. The `size` field in @a purpose must correctly indicate the * number of bytes of the data structure, including its header. If possible, * use #GNUNET_CRYPTO_eddsa_sign() instead of this function (only if @a validate * is not fixed-size, you must use this function directly). * * @param priv private key to use for the signing * @param purpose what to sign (size, purpose) * @param[out] sig where to write the signature * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_ ( const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig); /** * @ingroup crypto * @brief EdDSA sign a given block. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param priv private key to use for the signing * @param ps packed struct with what to sign, MUST begin with a purpose * @param[out] sig where to write the signature */ #define GNUNET_CRYPTO_eddsa_sign(priv,ps,sig) do { \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*ps)); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_assert (GNUNET_OK == \ GNUNET_CRYPTO_eddsa_sign_ (priv, \ &(ps)->purpose, \ sig)); \ } while (0) /** * @ingroup crypto * @brief ECDSA Sign a given block. * * The @a purpose data is the beginning of the data of which the signature is * to be created. The `size` field in @a purpose must correctly indicate the * number of bytes of the data structure, including its header. If possible, * use #GNUNET_CRYPTO_ecdsa_sign() instead of this function (only if @a validate * is not fixed-size, you must use this function directly). * * @param priv private key to use for the signing * @param purpose what to sign (size, purpose) * @param[out] sig where to write the signature * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_sign_ ( const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig); /** * @brief * * @param priv * @param data * @param size * @param sig * @return enum GNUNET_GenericReturnValue */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_raw ( const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, void *data, size_t size, struct GNUNET_CRYPTO_EddsaSignature *sig); /** * @ingroup crypto * @brief ECDSA sign a given block. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param priv private key to use for the signing * @param ps packed struct with what to sign, MUST begin with a purpose * @param[out] sig where to write the signature */ #define GNUNET_CRYPTO_ecdsa_sign(priv,ps,sig) do { \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_assert (GNUNET_OK == \ GNUNET_CRYPTO_ecdsa_sign_ (priv, \ &(ps)->purpose, \ sig)); \ } while (0) /** * @ingroup crypto * @brief Edx25519 sign a given block. * * The @a purpose data is the beginning of the data of which the signature is * to be created. The `size` field in @a purpose must correctly indicate the * number of bytes of the data structure, including its header. If possible, * use #GNUNET_CRYPTO_edx25519_sign() instead of this function (only if @a * validate is not fixed-size, you must use this function directly). * * @param priv private key to use for the signing * @param purpose what to sign (size, purpose) * @param[out] sig where to write the signature * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_edx25519_sign_ ( const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_Edx25519Signature *sig); /** * @ingroup crypto * @brief Edx25519 sign a given block. The resulting signature is compatible * with EdDSA. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param priv private key to use for the signing * @param ps packed struct with what to sign, MUST begin with a purpose * @param[out] sig where to write the signature */ #define GNUNET_CRYPTO_edx25519_sign(priv,ps,sig) do { \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_assert (GNUNET_OK == \ GNUNET_CRYPTO_edx25519_sign_ (priv, \ &(ps)->purpose, \ sig)); \ } while (0) /** * @ingroup crypto * @brief Verify EdDSA signature. * * The @a validate data is the beginning of the data of which the signature * is to be verified. The `size` field in @a validate must correctly indicate * the number of bytes of the data structure, including its header. If @a * purpose does not match the purpose given in @a validate (the latter must be * in big endian), signature verification fails. If possible, * use #GNUNET_CRYPTO_eddsa_verify() instead of this function (only if @a validate * is not fixed-size, you must use this function directly). * * @param purpose what is the purpose that the signature should have? * @param validate block to validate (size, purpose, data) * @param sig signature that is being validated * @param pub public key of the signer * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_ ( uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub); /** * @ingroup crypto * @brief Verify EdDSA signature. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param purp purpose of the signature, must match 'ps->purpose.purpose' * (except in host byte order) * @param priv private key to use for the signing * @param ps packed struct with what to sign, MUST begin with a purpose * @param sig where to write the signature */ #define GNUNET_CRYPTO_eddsa_verify(purp,ps,sig,pub) ({ \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_CRYPTO_eddsa_verify_ (purp, \ &(ps)->purpose, \ sig, \ pub); \ }) /** * @ingroup crypto * @brief Verify ECDSA signature. * * The @a validate data is the beginning of the data of which the signature is * to be verified. The `size` field in @a validate must correctly indicate the * number of bytes of the data structure, including its header. If @a purpose * does not match the purpose given in @a validate (the latter must be in big * endian), signature verification fails. If possible, use * #GNUNET_CRYPTO_eddsa_verify() instead of this function (only if @a validate * is not fixed-size, you must use this function directly). * * @param purpose what is the purpose that the signature should have? * @param validate block to validate (size, purpose, data) * @param sig signature that is being validated * @param pub public key of the signer * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_verify_ ( uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub); /** * @ingroup crypto * @brief Verify ECDSA signature. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param purp purpose of the signature, must match 'ps->purpose.purpose' * (except in host byte order) * @param priv private key to use for the signing * @param ps packed struct with what to sign, MUST begin with a purpose * @param sig where to write the signature */ #define GNUNET_CRYPTO_ecdsa_verify(purp,ps,sig,pub) ({ \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_CRYPTO_ecdsa_verify_ (purp, \ &(ps)->purpose, \ sig, \ pub); \ }) /** * @ingroup crypto * @brief Verify Edx25519 signature. * * The @a validate data is the beginning of the data of which the signature * is to be verified. The `size` field in @a validate must correctly indicate * the number of bytes of the data structure, including its header. If @a * purpose does not match the purpose given in @a validate (the latter must be * in big endian), signature verification fails. If possible, use * #GNUNET_CRYPTO_edx25519_verify() instead of this function (only if @a * validate is not fixed-size, you must use this function directly). * * @param purpose what is the purpose that the signature should have? * @param validate block to validate (size, purpose, data) * @param sig signature that is being validated * @param pub public key of the signer * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_edx25519_verify_ ( uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_Edx25519Signature *sig, const struct GNUNET_CRYPTO_Edx25519PublicKey *pub); /** * @ingroup crypto * @brief Verify Edx25519 signature. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param purp purpose of the signature, must match 'ps->purpose.purpose' * (except in host byte order) * @param priv private key to use for the signing * @param ps packed struct with what to sign, MUST begin with a purpose * @param sig where to write the signature */ #define GNUNET_CRYPTO_edx25519_verify(purp,ps,sig,pub) ({ \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_CRYPTO_edx25519_verify_ (purp, \ &(ps)->purpose, \ sig, \ pub); \ }) /** * @ingroup crypto * Derive a private key from a given private key and a label. * Essentially calculates a private key 'h = H(l,P) * d mod n' * where n is the size of the ECC group and P is the public * key associated with the private key 'd'. * * @param priv original private key * @param label label to use for key deriviation * @param context additional context to use for HKDF of 'h'; * typically the name of the subsystem/application * @return derived private key */ struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_private_key_derive ( const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const char *label, const char *context); /** * @ingroup crypto * Derive a public key from a given public key and a label. * Essentially calculates a public key 'V = H(l,P) * P'. * * @param pub original public key * @param label label to use for key deriviation * @param context additional context to use for HKDF of 'h'. * typically the name of the subsystem/application * @param result where to write the derived public key */ void GNUNET_CRYPTO_ecdsa_public_key_derive ( const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const char *label, const char *context, struct GNUNET_CRYPTO_EcdsaPublicKey *result); /** * This is a signature function for ECDSA which takes a * private key, derives/blinds it and signs the message. * * @param pkey original private key * @param label label to use for key deriviation * @param context additional context to use for HKDF of 'h'; * typically the name of the subsystem/application * @param purpose the signature purpose * @param sig the resulting signature * @return GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_sign_derived ( const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, const char *label, const char *context, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig); /** * @ingroup crypto * Derive a private scalar from a given private key and a label. * Essentially calculates a private key 'h = H(l,P) * d mod n' * where n is the size of the ECC group and P is the public * key associated with the private key 'd'. * The result is the derived private _scalar_, not the private * key as for EdDSA we cannot derive before we hash the * private key. * * @param priv original private key * @param label label to use for key deriviation * @param context additional context to use for HKDF of 'h'; * typically the name of the subsystem/application * @param result derived private scalar */ void GNUNET_CRYPTO_eddsa_private_key_derive ( const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const char *label, const char *context, struct GNUNET_CRYPTO_EddsaPrivateScalar *result); /** * @ingroup crypto * Derive a public key from a given public key and a label. * Essentially calculates a public key 'V = H(l,P) * P'. * * @param pub original public key * @param label label to use for key deriviation * @param context additional context to use for HKDF of 'h'. * typically the name of the subsystem/application * @param result where to write the derived public key */ void GNUNET_CRYPTO_eddsa_public_key_derive ( const struct GNUNET_CRYPTO_EddsaPublicKey *pub, const char *label, const char *context, struct GNUNET_CRYPTO_EddsaPublicKey *result); /** * This is a signature function for EdDSA which takes a * private key and derives it using the label and context * before signing. * * @param pkey original private key * @param label label to use for key deriviation * @param context additional context to use for HKDF of 'h'; * typically the name of the subsystem/application * @param purpose the signature purpose * @param sig the resulting signature * @return GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_derived ( const struct GNUNET_CRYPTO_EddsaPrivateKey *pkey, const char *label, const char *context, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig); /** * Extract the public key of the given private scalar. * * @param s the private scalar * @param pkey the resulting public key */ void GNUNET_CRYPTO_eddsa_key_get_public_from_scalar ( const struct GNUNET_CRYPTO_EddsaPrivateScalar *s, struct GNUNET_CRYPTO_EddsaPublicKey *pkey); /** * @ingroup crypto * Derive a private scalar from a given private key and a label. * Essentially calculates a private key 'h = H(l,P) * d mod n' * where n is the size of the ECC group and P is the public * key associated with the private key 'd'. * * @param priv original private key * @param seed input seed * @param seedsize size of the seed * @param result derived private key */ void GNUNET_CRYPTO_edx25519_private_key_derive ( const struct GNUNET_CRYPTO_Edx25519PrivateKey *priv, const void *seed, size_t seedsize, struct GNUNET_CRYPTO_Edx25519PrivateKey *result); /** * @ingroup crypto * Derive a public key from a given public key and a label. * Essentially calculates a public key 'V = H(l,P) * P'. * * @param pub original public key * @param seed input seed * @param seedsize size of the seed * @param result where to write the derived public key */ void GNUNET_CRYPTO_edx25519_public_key_derive ( const struct GNUNET_CRYPTO_Edx25519PublicKey *pub, const void *seed, size_t seedsize, struct GNUNET_CRYPTO_Edx25519PublicKey *result); /** * Note: Included in header for testing purposes. GNUNET_CRYPTO_ecdhe_elligator_decoding will be the correct API for the direct map. * TODO: Make static. * @ingroup crypto * Encodes an element of the underlying finite field, so called representative, of Curve25519 to a point on the curve * This transformation is deterministic * * @param representative element of the finite field * @param point destination for the calculated point on the curve * @param high_y destination set to "True" if corresponding y-coordinate is > 2 ^ 254 - 10 */ bool GNUNET_CRYPTO_ecdhe_elligator_direct_map (uint8_t *point, bool *high_y, uint8_t *representative); /** * @ingroup crypto * Clears the most significant bit and second most significant bit to the serialized representaive before applying elligator direct map. * * @param serialized_representative serialized version of an element of Curves25519's finite field * @param point destination for the calculated point on the curve * @param high_y destination set to "True" if corresponding y-coordinate is > 2 ^ 254 - 10 */ bool GNUNET_CRYPTO_ecdhe_elligator_decoding (struct GNUNET_CRYPTO_EcdhePublicKey *point, bool *high_y, struct GNUNET_CRYPTO_ElligatorRepresentative * seriliazed_representative); /** * @ingroup crypto * Encodes a point on Curve25519 to a an element of the underlying finite field * This transformation is deterministic * * @param point a point on the curve * @param high_y encodes if y-coordinate is > 2 ^254 - 10, which determines the representative value out of two * @param representative destination for the calculated element of the finite field */ bool GNUNET_CRYPTO_ecdhe_elligator_inverse_map (uint8_t *representative, const uint8_t *point, bool high_y); /** * Initializes the elligator library * THis function is thread safe */ void GNUNET_CRYPTO_ecdhe_elligator_initialize (void); /** * @ingroup crypto * Generates a valid public key for elligator's inverse map by adding a lower order point to a prime order point. * * @param pub valid public key for elligator inverse map * @param pk private key for generating valid public key */ int GNUNET_CRYPTO_ecdhe_elligator_generate_public_key (unsigned char pub[ crypto_scalarmult_SCALARBYTES ], struct GNUNET_CRYPTO_EcdhePrivateKey *pk); /** * @ingroup crypto * Generates a private key for Curve25519 and the elligator representative of the corresponding public key * * @param repr representative of the public key * @param pk Curve25519 private key * @return GNUNET_OK if creation successful */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdhe_elligator_key_create ( struct GNUNET_CRYPTO_ElligatorRepresentative *repr, struct GNUNET_CRYPTO_EcdhePrivateKey *pk); /** * 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 Encryption 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 @a 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 c1 * and @a c2 * * 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); /* ********* Chaum-style RSA-based blind signatures ******************* */ /** * The private information of an RSA key pair. */ struct GNUNET_CRYPTO_RsaPrivateKey; /** * The public information of an RSA key pair. */ struct GNUNET_CRYPTO_RsaPublicKey; /** * Constant-size pre-secret for blinding key generation. */ struct GNUNET_CRYPTO_RsaBlindingKeySecret { /** * Bits used to generate the blinding key. 256 bits * of entropy is enough. */ uint32_t pre_secret[8] GNUNET_PACKED; }; /** * @brief an RSA signature */ struct GNUNET_CRYPTO_RsaSignature; /** * Create a new private key. Caller must free return value. * * @param len length of the key in bits (e.g. 2048) * @return fresh private key */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_create (unsigned int len); /** * Free memory occupied by the private key. * * @param key pointer to the memory to free */ void GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key); /** * Encode the private key in a format suitable for * storing it into a file. * * @param key the private key * @param[out] buffer set to a buffer with the encoded key * @return size of memory allocatedin @a buffer */ size_t GNUNET_CRYPTO_rsa_private_key_encode ( const struct GNUNET_CRYPTO_RsaPrivateKey *key, void **buffer); /** * Decode the private key from the data-format back * to the "normal", internal format. * * @param buf the buffer where the private key data is stored * @param buf_size the size of the data in @a buf * @return NULL on error */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_decode (const void *buf, size_t buf_size); /** * Duplicate the given private key * * @param key the private key to duplicate * @return the duplicate key; NULL upon error */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_private_key_dup ( const struct GNUNET_CRYPTO_RsaPrivateKey *key); /** * Extract the public key of the given private key. * * @param priv the private key * @return NULL on error, otherwise the public key */ struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_private_key_get_public ( const struct GNUNET_CRYPTO_RsaPrivateKey *priv); /** * Compute hash over the public key. * * @param key public key to hash * @param hc where to store the hash code */ void GNUNET_CRYPTO_rsa_public_key_hash ( const struct GNUNET_CRYPTO_RsaPublicKey *key, struct GNUNET_HashCode *hc); /** * Check if @a key is well-formed. * * @return true if @a key is well-formed. */ bool GNUNET_CRYPTO_rsa_public_key_check ( const struct GNUNET_CRYPTO_RsaPublicKey *key); /** * Obtain the length of the RSA key in bits. * * @param key the public key to introspect * @return length of the key in bits */ unsigned int GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key); /** * Free memory occupied by the public key. * * @param key pointer to the memory to free */ void GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key); /** * Encode the public key in a format suitable for * storing it into a file. * * @param key the private key * @param[out] buffer set to a buffer with the encoded key * @return size of memory allocated in @a buffer */ size_t GNUNET_CRYPTO_rsa_public_key_encode ( const struct GNUNET_CRYPTO_RsaPublicKey *key, void **buffer); /** * Decode the public key from the data-format back * to the "normal", internal format. * * @param buf the buffer where the public key data is stored * @param len the length of the data in @a buf * @return NULL on error */ struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_public_key_decode (const char *buf, size_t len); /** * Duplicate the given public key * * @param key the public key to duplicate * @return the duplicate key; NULL upon error */ struct GNUNET_CRYPTO_RsaPublicKey * GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key); /** * Compare the values of two signatures. * * @param s1 one signature * @param s2 the other signature * @return 0 if the two are equal */ int GNUNET_CRYPTO_rsa_signature_cmp (const struct GNUNET_CRYPTO_RsaSignature *s1, const struct GNUNET_CRYPTO_RsaSignature *s2); /** * Compare the values of two private keys. * * @param p1 one private key * @param p2 the other private key * @return 0 if the two are equal */ int GNUNET_CRYPTO_rsa_private_key_cmp ( const struct GNUNET_CRYPTO_RsaPrivateKey *p1, const struct GNUNET_CRYPTO_RsaPrivateKey *p2); /** * Compare the values of two public keys. * * @param p1 one public key * @param p2 the other public key * @return 0 if the two are equal */ int GNUNET_CRYPTO_rsa_public_key_cmp (const struct GNUNET_CRYPTO_RsaPublicKey *p1, const struct GNUNET_CRYPTO_RsaPublicKey *p2); /** * @brief RSA Parameters to create blinded signature */ struct GNUNET_CRYPTO_RsaBlindedMessage { /** * Blinded message to be signed * Note: is malloc()'ed! */ void *blinded_msg; /** * Size of the @e blinded_msg to be signed. */ size_t blinded_msg_size; }; /** * Blinds the given message with the given blinding key * * @param message the message to sign * @param message_size number of bytes in @a message * @param bks the blinding key * @param pkey the public key of the signer * @param[out] bm set to the blinded message * @return #GNUNET_YES if successful, #GNUNET_NO if RSA key is malicious */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_blind (const void *message, size_t message_size, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey, struct GNUNET_CRYPTO_RsaBlindedMessage *bm); /** * Sign a blinded value, which must be a full domain hash of a message. * * @param key private key to use for the signing * @param bm the (blinded) message to sign * @return NULL on error, signature on success */ struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_CRYPTO_RsaBlindedMessage *bm); /** * Create and sign a full domain hash of a message. * * @param key private key to use for the signing * @param message the message to sign * @param message_size number of bytes in @a message * @return NULL on error, including a malicious RSA key, signature on success */ struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key, const void *message, size_t message_size); /** * Free memory occupied by blinded message. Only frees contents, not * @a bm itself. * * @param[in] bm memory to free */ void GNUNET_CRYPTO_rsa_blinded_message_free ( struct GNUNET_CRYPTO_RsaBlindedMessage *bm); /** * Free memory occupied by signature. * * @param[in] sig memory to free */ void GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig); /** * Encode the given signature in a format suitable for storing it into a file. * * @param sig the signature * @param[out] buffer set to a buffer with the encoded key * @return size of memory allocated in @a buffer */ size_t GNUNET_CRYPTO_rsa_signature_encode ( const struct GNUNET_CRYPTO_RsaSignature *sig, void **buffer); /** * Decode the signature from the data-format back to the "normal", internal * format. * * @param buf the buffer where the public key data is stored * @param buf_size the number of bytes of the data in @a buf * @return NULL on error */ struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_signature_decode ( const void *buf, size_t buf_size); /** * Duplicate the given rsa signature * * @param sig the signature to duplicate * @return the duplicate key; NULL upon error */ struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_signature_dup ( const struct GNUNET_CRYPTO_RsaSignature *sig); /** * Unblind a blind-signed signature. The signature should have been generated * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with * #GNUNET_CRYPTO_rsa_blind(). * * @param sig the signature made on the blinded signature purpose * @param bks the blinding key secret used to blind the signature purpose * @param pkey the public key of the signer * @return unblinded signature on success, NULL if RSA key is bad or malicious. */ struct GNUNET_CRYPTO_RsaSignature * GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks, struct GNUNET_CRYPTO_RsaPublicKey *pkey); /** * Verify whether the given hash corresponds to the given signature and the * signature is valid with respect to the given public key. * * @param message the message to sign * @param message_size number of bytes in @a message * @param sig signature that is being validated * @param public_key public key of the signer * @returns #GNUNET_YES if ok, #GNUNET_NO if RSA key is malicious, #GNUNET_SYSERR if signature */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_rsa_verify (const void *message, size_t message_size, const struct GNUNET_CRYPTO_RsaSignature *sig, const struct GNUNET_CRYPTO_RsaPublicKey *public_key); /** * Create a new random private key. * * @param[out] priv where to write the fresh private key */ void GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv); /** * Extract the public key of the given private key. * * @param priv the private key * @param[out] pub where to write the public key */ void GNUNET_CRYPTO_cs_private_key_get_public ( const struct GNUNET_CRYPTO_CsPrivateKey *priv, struct GNUNET_CRYPTO_CsPublicKey *pub); /** * Derive a new secret r pair r0 and r1. * In original papers r is generated randomly * To provide abort-idempotency, r needs to be derived but still needs to be UNPREDICTABLE * To ensure unpredictability a new nonce should be used when a new r needs to be derived. * Uses HKDF internally. * Comment: Can be done in one HKDF shot and split output. * * @param nonce is a random nonce * @param seed seed to use in derivation * @param lts is a long-term-secret in form of a private key * @param[out] r array containing derived secrets r0 and r1 */ void GNUNET_CRYPTO_cs_r_derive ( const struct GNUNET_CRYPTO_CsSessionNonce *nonce, const char *seed, const struct GNUNET_CRYPTO_CsPrivateKey *lts, struct GNUNET_CRYPTO_CsRSecret r[2]); /** * Extract the public R of the given secret r. * * @param r_priv the private key * @param[out] r_pub where to write the public key */ void GNUNET_CRYPTO_cs_r_get_public ( const struct GNUNET_CRYPTO_CsRSecret *r_priv, struct GNUNET_CRYPTO_CsRPublic *r_pub); /** * Derives new random blinding factors. * In original papers blinding factors are generated randomly * To provide abort-idempotency, blinding factors need to be derived but still need to be UNPREDICTABLE. * To ensure unpredictability a new nonce has to be used. * Uses HKDF internally. * * @param blind_seed is the blinding seed to derive blinding factors * @param[out] bs array containing the two derived blinding secrets */ void GNUNET_CRYPTO_cs_blinding_secrets_derive ( const struct GNUNET_CRYPTO_CsBlindingNonce *blind_seed, struct GNUNET_CRYPTO_CsBlindingSecret bs[2]); /** * @brief CS Parameters derived from the message * during blinding to create blinded signature */ struct GNUNET_CRYPTO_CsBlindedMessage { /** * The Clause Schnorr c_0 and c_1 containing the blinded message */ struct GNUNET_CRYPTO_CsC c[2]; /** * Nonce used in initial request. */ struct GNUNET_CRYPTO_CsSessionNonce nonce; }; /** * Pair of Public R values for Cs denominations */ struct GNUNET_CRYPTO_CSPublicRPairP { struct GNUNET_CRYPTO_CsRPublic r_pub[2]; }; /** * Calculate two blinded c's. * Comment: One would be insecure due to Wagner's algorithm solving ROS * * @param bs array of the two blinding factor structs each containing alpha and beta * @param r_pub array of the two signer's nonce R * @param pub the public key of the signer * @param msg the message to blind in preparation for signing * @param msg_len length of message msg * @param[out] blinded_c array of the two blinded c's * @param[out] r_pub_blind array of the two blinded R */ void GNUNET_CRYPTO_cs_calc_blinded_c ( const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], const struct GNUNET_CRYPTO_CsRPublic r_pub[2], const struct GNUNET_CRYPTO_CsPublicKey *pub, const void *msg, size_t msg_len, struct GNUNET_CRYPTO_CsC blinded_c[2], struct GNUNET_CRYPTO_CSPublicRPairP *r_pub_blind); /** * The Sign Answer for Clause Blind Schnorr signature. * The sign operation returns a parameter @param b and the signature * scalar @param s_scalar. */ struct GNUNET_CRYPTO_CsBlindSignature { /** * To make ROS problem harder, the signer chooses an unpredictable b and * only calculates signature of c_b */ unsigned int b; /** * The blinded s scalar calculated from c_b */ struct GNUNET_CRYPTO_CsBlindS s_scalar; }; /** * Sign a blinded @a c. * This function derives b from a nonce and a longterm secret. * In the original papers b is generated randomly. * To provide abort-idempotency, b needs to be derived but still need to be UNPREDICTABLE. * To ensure unpredictability a new nonce has to be used for every signature. * HKDF is used internally for derivation. * r0 and r1 can be derived prior by using GNUNET_CRYPTO_cs_r_derive. * * @param priv private key to use for the signing and as LTS in HKDF * @param r array of the two secret inputs from the signer * @param bm blinded message, including array of the two blinded c to sign c_b and the random nonce * @param[out] cs_blind_sig where to write the blind signature */ void GNUNET_CRYPTO_cs_sign_derive ( const struct GNUNET_CRYPTO_CsPrivateKey *priv, const struct GNUNET_CRYPTO_CsRSecret r[2], const struct GNUNET_CRYPTO_CsBlindedMessage *bm, struct GNUNET_CRYPTO_CsBlindSignature *cs_blind_sig); /** * Unblind a blind-signed signature using a c that was blinded * * @param blinded_signature_scalar the signature made on the blinded c * @param bs the blinding factors used in the blinding * @param[out] signature_scalar where to write the unblinded signature */ void GNUNET_CRYPTO_cs_unblind ( const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, const struct GNUNET_CRYPTO_CsBlindingSecret *bs, struct GNUNET_CRYPTO_CsS *signature_scalar); /** * Verify whether the given message corresponds to the given signature and the * signature is valid with respect to the given public key. * * @param sig signature that is being validated * @param pub public key of the signer * @param msg is the message that should be signed by @a sig (message is used to calculate c) * @param msg_len is the message length * @returns #GNUNET_YES on success, #GNUNET_SYSERR if signature invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_cs_verify ( const struct GNUNET_CRYPTO_CsSignature *sig, const struct GNUNET_CRYPTO_CsPublicKey *pub, const void *msg, size_t msg_len); /** * Types of public keys used for blind signatures. */ enum GNUNET_CRYPTO_BlindSignatureAlgorithm { /** * Invalid type of signature. */ GNUNET_CRYPTO_BSA_INVALID = 0, /** * RSA blind signature. */ GNUNET_CRYPTO_BSA_RSA = 1, /** * Clause Blind Schnorr signature. */ GNUNET_CRYPTO_BSA_CS = 2 }; /** * @brief Type of (unblinded) signatures. */ struct GNUNET_CRYPTO_UnblindedSignature { /** * Type of the signature. */ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** * Reference counter. */ unsigned int rc; /** * Details, depending on @e cipher. */ union { /** * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. */ struct GNUNET_CRYPTO_CsSignature cs_signature; /** * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. */ struct GNUNET_CRYPTO_RsaSignature *rsa_signature; } details; }; /** * @brief Type for *blinded* signatures. * Must be unblinded before it becomes valid. */ struct GNUNET_CRYPTO_BlindedSignature { /** * Type of the signature. */ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** * Reference counter. */ unsigned int rc; /** * Details, depending on @e cipher. */ union { /** * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. * At this point only the blinded s scalar is used. * The final signature consisting of r,s is built after unblinding. */ struct GNUNET_CRYPTO_CsBlindSignature blinded_cs_answer; /** * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. */ struct GNUNET_CRYPTO_RsaSignature *blinded_rsa_signature; } details; }; /** * @brief Type of public signing keys for blind signatures. */ struct GNUNET_CRYPTO_BlindSignPublicKey { /** * Type of the public key. */ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** * Reference counter. */ unsigned int rc; /** * Hash of the public key. */ struct GNUNET_HashCode pub_key_hash; /** * Details, depending on @e cipher. */ union { /** * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. */ struct GNUNET_CRYPTO_CsPublicKey cs_public_key; /** * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. */ struct GNUNET_CRYPTO_RsaPublicKey *rsa_public_key; } details; }; /** * @brief Type of private signing keys for blind signing. */ struct GNUNET_CRYPTO_BlindSignPrivateKey { /** * Type of the public key. */ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** * Reference counter. */ unsigned int rc; /** * Details, depending on @e cipher. */ union { /** * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. */ struct GNUNET_CRYPTO_CsPrivateKey cs_private_key; /** * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. */ struct GNUNET_CRYPTO_RsaPrivateKey *rsa_private_key; } details; }; /** * @brief Blinded message ready for blind signing. */ struct GNUNET_CRYPTO_BlindedMessage { /** * Type of the sign blinded message */ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** * Reference counter. */ unsigned int rc; /** * Details, depending on @e cipher. */ union { /** * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. */ struct GNUNET_CRYPTO_CsBlindedMessage cs_blinded_message; /** * If we use #GNUNET_CRYPTO_BSA_RSA in @a cipher. */ struct GNUNET_CRYPTO_RsaBlindedMessage rsa_blinded_message; } details; }; /** * Secret r for Cs denominations */ struct GNUNET_CRYPTO_CSPrivateRPairP { struct GNUNET_CRYPTO_CsRSecret r[2]; }; /** * @brief Input needed for blinding a message. */ struct GNUNET_CRYPTO_BlindingInputValues { /** * Type of the signature. */ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher; /** * Reference counter. */ unsigned int rc; /** * Details, depending on @e cipher. */ union { /** * If we use #GNUNET_CRYPTO_BSA_CS in @a cipher. */ struct GNUNET_CRYPTO_CSPublicRPairP cs_values; } details; }; /** * Nonce used to deterministiacally derive input values * used in multi-round blind signature protocols. */ union GNUNET_CRYPTO_BlindSessionNonce { /** * Nonce used when signing with CS. */ struct GNUNET_CRYPTO_CsSessionNonce cs_nonce; }; /** * Compute blinding input values for a given @a nonce and * @a salt. * * @param bsign_priv private key to compute input values for * @param nonce session nonce to derive input values from * @param salt salt to include in derivation logic * @return blinding input values */ struct GNUNET_CRYPTO_BlindingInputValues * GNUNET_CRYPTO_get_blinding_input_values ( const struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv, const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const char *salt); /** * Decrement reference counter of a @a bsign_pub, and free it if it reaches zero. * * @param[in] bsign_pub key to free */ void GNUNET_CRYPTO_blind_sign_pub_decref ( struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub); /** * Decrement reference counter of a @a bsign_priv, and free it if it reaches zero. * * @param[in] bsign_priv key to free */ void GNUNET_CRYPTO_blind_sign_priv_decref ( struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv); /** * Decrement reference counter of a @a ub_sig, and free it if it reaches zero. * * @param[in] ub_sig signature to free */ void GNUNET_CRYPTO_unblinded_sig_decref ( struct GNUNET_CRYPTO_UnblindedSignature *ub_sig); /** * Decrement reference counter of a @a blind_sig, and free it if it reaches zero. * * @param[in] blind_sig signature to free */ void GNUNET_CRYPTO_blinded_sig_decref ( struct GNUNET_CRYPTO_BlindedSignature *blind_sig); /** * Decrement reference counter of a @a bm, and free it if it reaches zero. * * @param[in] bm blinded message to free */ void GNUNET_CRYPTO_blinded_message_decref ( struct GNUNET_CRYPTO_BlindedMessage *bm); /** * Increment reference counter of the given @a bm. * * @param[in,out] bm blinded message to increment reference counter for * @return alias of @a bm with RC incremented */ struct GNUNET_CRYPTO_BlindedMessage * GNUNET_CRYPTO_blinded_message_incref ( struct GNUNET_CRYPTO_BlindedMessage *bm); /** * Increment reference counter of the given @a bi. * * @param[in,out] bi blinding input values to increment reference counter for * @return alias of @a bi with RC incremented */ struct GNUNET_CRYPTO_BlindingInputValues * GNUNET_CRYPTO_blinding_input_values_incref ( struct GNUNET_CRYPTO_BlindingInputValues *bm); /** * Decrement reference counter of the given @a bi, and free it if it reaches * zero. * * @param[in,out] bi blinding input values to decrement reference counter for */ void GNUNET_CRYPTO_blinding_input_values_decref ( struct GNUNET_CRYPTO_BlindingInputValues *bm); /** * Increment reference counter of the given @a bsign_pub. * * @param[in,out] bsign_pub public key to increment reference counter for * @return alias of @a bsign_pub with RC incremented */ struct GNUNET_CRYPTO_BlindSignPublicKey * GNUNET_CRYPTO_bsign_pub_incref ( struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub); /** * Increment reference counter of the given @a bsign_priv. * * @param[in,out] bsign_priv private key to increment reference counter for * @return alias of @a bsign_priv with RC incremented */ struct GNUNET_CRYPTO_BlindSignPrivateKey * GNUNET_CRYPTO_bsign_priv_incref ( struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv); /** * Increment reference counter of the given @a ub_sig. * * @param[in,out] ub_sig signature to increment reference counter for * @return alias of @a ub_sig with RC incremented */ struct GNUNET_CRYPTO_UnblindedSignature * GNUNET_CRYPTO_ub_sig_incref (struct GNUNET_CRYPTO_UnblindedSignature *ub_sig); /** * Increment reference counter of the given @a blind_sig. * * @param[in,out] blind_sig signature to increment reference counter for * @return alias of @a blind_sig with RC incremented */ struct GNUNET_CRYPTO_BlindedSignature * GNUNET_CRYPTO_blind_sig_incref ( struct GNUNET_CRYPTO_BlindedSignature *blind_sig); /** * Compare two denomination public keys. * * @param bp1 first key * @param bp2 second key * @return 0 if the keys are equal, otherwise -1 or 1 */ int GNUNET_CRYPTO_bsign_pub_cmp ( const struct GNUNET_CRYPTO_BlindSignPublicKey *bp1, const struct GNUNET_CRYPTO_BlindSignPublicKey *bp2); /** * Compare two denomination signatures. * * @param sig1 first signature * @param sig2 second signature * @return 0 if the keys are equal, otherwise -1 or 1 */ int GNUNET_CRYPTO_ub_sig_cmp (const struct GNUNET_CRYPTO_UnblindedSignature *sig1, const struct GNUNET_CRYPTO_UnblindedSignature *sig2); /** * Compare two blinded denomination signatures. * * @param sig1 first signature * @param sig2 second signature * @return 0 if the keys are equal, otherwise -1 or 1 */ int GNUNET_CRYPTO_blind_sig_cmp ( const struct GNUNET_CRYPTO_BlindedSignature *sig1, const struct GNUNET_CRYPTO_BlindedSignature *sig2); /** * Compare two blinded messages. * * @param bp1 first blinded message * @param bp2 second blinded message * @return 0 if the keys are equal, otherwise -1 or 1 */ int GNUNET_CRYPTO_blinded_message_cmp ( const struct GNUNET_CRYPTO_BlindedMessage *bp1, const struct GNUNET_CRYPTO_BlindedMessage *bp2); /** * Initialize public-private key pair for blind signatures. * * For #GNUNET_CRYPTO_BSA_RSA, an additional "unsigned int" * argument with the number of bits for 'n' (e.g. 2048) must * be passed. * * @param[out] bsign_priv where to write the private key with RC 1 * @param[out] bsign_pub where to write the public key with RC 1 * @param cipher which type of cipher to use * @param ... RSA key size (eg. 2048/3072/4096) * @return #GNUNET_OK on success, #GNUNET_NO if parameterst were invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_blind_sign_keys_create ( struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, ...); /** * Initialize public-private key pair for blind signatures. * * For #GNUNET_CRYPTO_BSA_RSA, an additional "unsigned int" * argument with the number of bits for 'n' (e.g. 2048) must * be passed. * * @param[out] bsign_priv where to write the private key with RC 1 * @param[out] bsign_pub where to write the public key with RC 1 * @param cipher which type of cipher to use * @param ap RSA key size (eg. 2048/3072/4096) * @return #GNUNET_OK on success, #GNUNET_NO if parameterst were invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_blind_sign_keys_create_va ( struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, va_list ap); /** * @brief Type of blinding secrets. Must be exactly 32 bytes (DB). */ union GNUNET_CRYPTO_BlindingSecretP { /** * Clause Schnorr nonce. */ struct GNUNET_CRYPTO_CsBlindingNonce nonce; /** * Variant for RSA for blind signatures. */ struct GNUNET_CRYPTO_RsaBlindingKeySecret rsa_bks; }; /** * Blind message for blind signing with @a dk using blinding secret @a coin_bks. * * @param bsign_pub public key to blind for * @param bks blinding secret to use * @param nonce nonce used to obtain @a alg_values * can be NULL if input values are not used for the cipher * @param message message to sign * @param message_size number of bytes in @a message * @param alg_values algorithm specific values to blind the @a message * @return blinded message to give to signer, NULL on error */ struct GNUNET_CRYPTO_BlindedMessage * GNUNET_CRYPTO_message_blind_to_sign ( const struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub, const union GNUNET_CRYPTO_BlindingSecretP *bks, const union GNUNET_CRYPTO_BlindSessionNonce *nonce, const void *message, size_t message_size, const struct GNUNET_CRYPTO_BlindingInputValues *alg_values); /** * Create blind signature. * * @param bsign_priv private key to use for signing * @param salt salt value to use for the HKDF, * can be NULL if input values are not used for the cipher * @param blinded_message the already blinded message to sign * @return blind signature with RC=1, NULL on failure */ struct GNUNET_CRYPTO_BlindedSignature * GNUNET_CRYPTO_blind_sign ( const struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv, const char *salt, const struct GNUNET_CRYPTO_BlindedMessage *blinded_message); /** * Unblind blind signature. * * @param blinded_sig the blind signature * @param bks blinding secret to use * @param message message that was supposedly signed * @param message_size number of bytes in @a message * @param alg_values algorithm specific values * @param bsign_pub public key used for signing * @return unblinded signature with RC=1, NULL on error */ struct GNUNET_CRYPTO_UnblindedSignature * GNUNET_CRYPTO_blind_sig_unblind ( const struct GNUNET_CRYPTO_BlindedSignature *blinded_sig, const union GNUNET_CRYPTO_BlindingSecretP *bks, const void *message, size_t message_size, const struct GNUNET_CRYPTO_BlindingInputValues *alg_values, const struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub); /** * Verify signature made blindly. * * @param bsign_pub public key * @param ub_sig signature made blindly with the private key * @param message message that was supposedly signed * @param message_size number of bytes in @a message * @return #GNUNET_OK if the signature is valid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_blind_sig_verify ( const struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub, const struct GNUNET_CRYPTO_UnblindedSignature *ub_sig, const void *message, size_t message_size); /** * Get the compacted length of a #GNUNET_CRYPTO_PublicKey. * Compacted means that it returns the minimum number of bytes this * key is long, as opposed to the union structure inside * #GNUNET_CRYPTO_PublicKey. * Useful for compact serializations. * * @param key the key. * @return -1 on error, else the compacted length of the key. */ ssize_t GNUNET_CRYPTO_public_key_get_length (const struct GNUNET_CRYPTO_PublicKey *key); /** * Reads a #GNUNET_CRYPTO_PublicKey from a compact buffer. * The buffer has to contain at least the compacted length of * a #GNUNET_CRYPTO_PublicKey in bytes. * If the buffer is too small, the function returns -1 as error. * If the buffer does not contain a valid key, it returns -2 as error. * * @param buffer the buffer * @param len the length of buffer * @param key the key * @param the amount of bytes read from the buffer * @return #GNUNET_SYSERR on error */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_public_key_from_buffer ( const void *buffer, size_t len, struct GNUNET_CRYPTO_PublicKey *key, size_t *read); /** * Get the compacted length of a #GNUNET_CRYPTO_PrivateKey. * Compacted means that it returns the minimum number of bytes this * key is long, as opposed to the union structure inside * #GNUNET_CRYPTO_PrivateKey. * Useful for compact serializations. * * @param key the key. * @return -1 on error, else the compacted length of the key. */ ssize_t GNUNET_CRYPTO_private_key_get_length ( const struct GNUNET_CRYPTO_PrivateKey *key); /** * Writes a #GNUNET_CRYPTO_PublicKey to a compact buffer. * The buffer requires space for at least the compacted length of * a #GNUNET_CRYPTO_PublicKey in bytes. * If the buffer is too small, the function returns -1 as error. * If the key is not valid, it returns -2 as error. * * @param key the key * @param buffer the buffer * @param len the length of buffer * @return -1 or -2 on error, else the amount of bytes written to the buffer */ ssize_t GNUNET_CRYPTO_write_public_key_to_buffer (const struct GNUNET_CRYPTO_PublicKey *key, void*buffer, size_t len); /** * Reads a #GNUNET_CRYPTO_PrivateKey from a compact buffer. * The buffer has to contain at least the compacted length of * a #GNUNET_CRYPTO_PrivateKey in bytes. * If the buffer is too small, the function returns GNUNET_SYSERR as error. * * @param buffer the buffer * @param len the length of buffer * @param key the key * @param the amount of bytes read from the buffer * @return #GNUNET_SYSERR on error */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_read_private_key_from_buffer ( const void*buffer, size_t len, struct GNUNET_CRYPTO_PrivateKey *key, size_t *read); /** * Writes a #GNUNET_CRYPTO_PrivateKey to a compact buffer. * The buffer requires space for at least the compacted length of * a #GNUNET_CRYPTO_PrivateKey in bytes. * If the buffer is too small, the function returns -1 as error. * If the key is not valid, it returns -2 as error. * * @param key the key * @param buffer the buffer * @param len the length of buffer * @return -1 or -2 on error, else the amount of bytes written to the buffer */ ssize_t GNUNET_CRYPTO_write_private_key_to_buffer ( const struct GNUNET_CRYPTO_PrivateKey *key, void*buffer, size_t len); /** * Get the compacted length of a #GNUNET_CRYPTO_Signature. * Compacted means that it returns the minimum number of bytes this * signature is long, as opposed to the union structure inside * #GNUNET_CRYPTO_Signature. * Useful for compact serializations. * * @param sig the signature. * @return -1 on error, else the compacted length of the signature. */ ssize_t GNUNET_CRYPTO_signature_get_length ( const struct GNUNET_CRYPTO_Signature *sig); /** * Get the compacted length of a signature by type. * Compacted means that it returns the minimum number of bytes this * signature is long, as opposed to the union structure inside * #GNUNET_CRYPTO_Signature. * Useful for compact serializations. * * @param sig the signature. * @return -1 on error, else the compacted length of the signature. */ ssize_t GNUNET_CRYPTO_signature_get_raw_length_by_type (uint32_t type); /** * Reads a #GNUNET_CRYPTO_Signature from a compact buffer. * The buffer has to contain at least the compacted length of * a #GNUNET_CRYPTO_Signature in bytes. * If the buffer is too small, the function returns -1 as error. * If the buffer does not contain a valid key, it returns -2 as error. * * @param sig the signature * @param buffer the buffer * @param len the length of buffer * @return -1 or -2 on error, else the amount of bytes read from the buffer */ ssize_t GNUNET_CRYPTO_read_signature_from_buffer ( struct GNUNET_CRYPTO_Signature *sig, const void*buffer, size_t len); /** * Writes a #GNUNET_CRYPTO_Signature to a compact buffer. * The buffer requires space for at least the compacted length of * a #GNUNET_CRYPTO_Signature in bytes. * If the buffer is too small, the function returns -1 as error. * If the key is not valid, it returns -2 as error. * * @param sig the signature * @param buffer the buffer * @param len the length of buffer * @return -1 or -2 on error, else the amount of bytes written to the buffer */ ssize_t GNUNET_CRYPTO_write_signature_to_buffer ( const struct GNUNET_CRYPTO_Signature *sig, void*buffer, size_t len); /** * @brief Sign a given block. * * The @a purpose data is the beginning of the data of which the signature is * to be created. The `size` field in @a purpose must correctly indicate the * number of bytes of the data structure, including its header. If possible, * use #GNUNET_CRYPTO_sign() instead of this function. * * @param priv private key to use for the signing * @param purpose what to sign (size, purpose) * @param[out] sig where to write the signature * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_sign_ ( const struct GNUNET_CRYPTO_PrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_Signature *sig); /** * @brief Sign a given block. * * The @a purpose data is the beginning of the data of which the signature is * to be created. The `size` field in @a purpose must correctly indicate the * number of bytes of the data structure, including its header. * The signature payload and length depends on the key type. * * @param priv private key to use for the signing * @param purpose what to sign (size, purpose) * @param[out] sig where to write the signature * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_sign_raw_ ( const struct GNUNET_CRYPTO_PrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, unsigned char *sig); /** * @brief Sign a given block with #GNUNET_CRYPTO_PrivateKey. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param priv private key to use for the signing * @param ps packed struct with what to sign, MUST begin with a purpose * @param[out] sig where to write the signature */ #define GNUNET_CRYPTO_sign(priv,ps,sig) do { \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_assert (GNUNET_OK == \ GNUNET_CRYPTO_sign_ (priv, \ &(ps)->purpose, \ sig)); \ } while (0) /** * @brief Verify a given signature. * * The @a validate data is the beginning of the data of which the signature * is to be verified. The `size` field in @a validate must correctly indicate * the number of bytes of the data structure, including its header. If @a * purpose does not match the purpose given in @a validate (the latter must be * in big endian), signature verification fails. If possible, * use #GNUNET_CRYPTO_signature_verify() instead of this function (only if @a validate * is not fixed-size, you must use this function directly). * * @param purpose what is the purpose that the signature should have? * @param validate block to validate (size, purpose, data) * @param sig signature that is being validated * @param pub public key of the signer * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_signature_verify_ ( uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_Signature *sig, const struct GNUNET_CRYPTO_PublicKey *pub); /** * @brief Verify a given signature. * * The @a validate data is the beginning of the data of which the signature * is to be verified. The `size` field in @a validate must correctly indicate * the number of bytes of the data structure, including its header. If @a * purpose does not match the purpose given in @a validate (the latter must be * in big endian), signature verification fails. * * @param purpose what is the purpose that the signature should have? * @param validate block to validate (size, purpose, data) * @param sig signature that is being validated * @param pub public key of the signer * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_signature_verify_raw_ ( uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const unsigned char *sig, const struct GNUNET_CRYPTO_PublicKey *pub); /** * @brief Verify a given signature with #GNUNET_CRYPTO_PublicKey. * * The @a ps data must be a fixed-size struct for which the signature is to be * created. The `size` field in @a ps->purpose must correctly indicate the * number of bytes of the data structure, including its header. * * @param purp purpose of the signature, must match 'ps->purpose.purpose' * (except in host byte order) * @param ps packed struct with what to sign, MUST begin with a purpose * @param sig where to read the signature from * @param pub public key to use for the verifying */ #define GNUNET_CRYPTO_signature_verify(purp,ps,sig,pub) ({ \ /* check size is set correctly */ \ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*(ps))); \ /* check 'ps' begins with the purpose */ \ GNUNET_static_assert (((void*) (ps)) == \ ((void*) &(ps)->purpose)); \ GNUNET_CRYPTO_signature_verify_ (purp, \ &(ps)->purpose, \ sig, \ pub); \ }) /** * Encrypt a block with #GNUNET_CRYPTO_PublicKey and derives a * #GNUNET_CRYPTO_EcdhePublicKey which is required for decryption * using ecdh to derive a symmetric key. * * @param block the block to encrypt * @param size the size of the @a block * @param pub public key to use for ecdh * @param ecc where to write the ecc public key * @param result the output parameter in which to store the encrypted result * can be the same or overlap with @c block * @returns the size of the encrypted block, -1 for errors. * Due to the use of CFB and therefore an effective stream cipher, * this size should be the same as @c len. */ ssize_t GNUNET_CRYPTO_encrypt_old (const void *block, size_t size, const struct GNUNET_CRYPTO_PublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *ecc, void *result); /** * Decrypt a given block with #GNUNET_CRYPTO_PrivateKey and a given * #GNUNET_CRYPTO_EcdhePublicKey using ecdh to derive a symmetric key. * * @param block the data to decrypt, encoded as returned by encrypt * @param size the size of the @a block to decrypt * @param priv private key to use for ecdh * @param ecc the ecc public key * @param result address to store the result at * can be the same or overlap with @c block * @return -1 on failure, size of decrypted block on success. * Due to the use of CFB and therefore an effective stream cipher, * this size should be the same as @c size. */ ssize_t GNUNET_CRYPTO_decrypt_old ( const void *block, size_t size, const struct GNUNET_CRYPTO_PrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *ecc, void *result); #define GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES (crypto_secretbox_MACBYTES \ + sizeof (struct \ GNUNET_CRYPTO_FoKemC)) /** * Encrypt a block with #GNUNET_CRYPTO_PublicKey and derives a * #GNUNET_CRYPTO_EcdhePublicKey which is required for decryption * using ecdh to derive a symmetric key. * * Note that the result buffer for the ciphertext must be the length of * the message to encrypt plus #GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES. * * @param block the block to encrypt * @param size the size of the @a block * @param pub public key to encrypt for * @param result the output parameter in which to store the encrypted result * can be the same or overlap with @c block * @returns GNUNET_OK on success. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_encrypt (const void *block, size_t size, const struct GNUNET_CRYPTO_PublicKey *pub, void *result, size_t result_size); /** * Decrypt a given block with #GNUNET_CRYPTO_PrivateKey and a given * #GNUNET_CRYPTO_EcdhePublicKey using ecdh to derive a symmetric key. * * @param block the data to decrypt, encoded as returned by encrypt * @param size the size of the @a block to decrypt * @param priv private key to use for ecdh * @param result address to store the result at * can be the same or overlap with @c block * @returns GNUNET_OK on success. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_decrypt (const void *block, size_t size, const struct GNUNET_CRYPTO_PrivateKey *priv, void *result, size_t result_size); /** * Creates a (Base32) string representation of the public key. * The resulting string encodes a compacted representation of the key. * See also #GNUNET_CRYPTO_key_get_length. * * @param key the key. * @return the string representation of the key, or NULL on error. */ char * GNUNET_CRYPTO_public_key_to_string ( const struct GNUNET_CRYPTO_PublicKey *key); /** * Creates a (Base32) string representation of the private key. * The resulting string encodes a compacted representation of the key. * See also #GNUNET_CRYPTO_key_get_length. * * @param key the key. * @return the string representation of the key, or NULL on error. */ char * GNUNET_CRYPTO_private_key_to_string ( const struct GNUNET_CRYPTO_PrivateKey *key); /** * Parses a (Base32) string representation of the public key. * See also #GNUNET_CRYPTO_public_key_to_string. * * @param str the encoded key. * @param key where to write the key. * @return GNUNET_SYSERR on error. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_public_key_from_string (const char*str, struct GNUNET_CRYPTO_PublicKey *key); /** * Parses a (Base32) string representation of the private key. * See also #GNUNET_CRYPTO_private_key_to_string. * * @param str the encoded key. * @param key where to write the key. * @return GNUNET_SYSERR on error. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_private_key_from_string (const char*str, struct GNUNET_CRYPTO_PrivateKey *key); /** * Retrieves the public key representation of a private key. * * @param privkey the private key. * @param key the public key result. * @return GNUNET_SYSERR on error. */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_key_get_public (const struct GNUNET_CRYPTO_PrivateKey *privkey, struct GNUNET_CRYPTO_PublicKey *key); #if 0 /* keep Emacsens' auto-indent happy */ { #endif #ifdef __cplusplus } #endif /* ifndef GNUNET_CRYPTO_LIB_H */ #endif /** @} */ /* end of group addition */ /* end of gnunet_crypto_lib.h */