You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

443 lines
14 KiB

#ifndef LIBWALLY_CORE_CRYPTO_H
#define LIBWALLY_CORE_CRYPTO_H
#include "wally_core.h"
#include <stdint.h>
#include <stdlib.h>
/**
* Derive a pseudorandom key from inputs using an expensive application
* of HMAC SHA-256.
*
* @pass: Password to derive from.
* @pass_len: Length of @pass in bytes.
* @salt: Salt to derive from.
* @salt_len: Length of @salt in bytes.
* @cost: The cost of the function. The larger this number, the
* longer the key will take to derive.
* @block_size: The size of memory blocks required.
* @parallelism: Parallelism factor.
* @bytes_out: Destination for the derived pseudorandom key.
* @len: The length of @bytes_out in bytes.
*/
WALLY_CORE_API int wally_scrypt(
const unsigned char *pass,
size_t pass_len,
const unsigned char *salt,
size_t salt_len,
uint32_t cost,
uint32_t block_size,
uint32_t parallelism,
unsigned char *bytes_out,
size_t len);
#define AES_BLOCK_LEN 16 /** Length of AES encrypted blocks */
#define AES_KEY_LEN_128 16 /** AES-128 Key length */
#define AES_KEY_LEN_192 24 /** AES-192 Key length */
#define AES_KEY_LEN_256 32 /** AES-256 Key length */
#define AES_FLAG_ENCRYPT 1 /** Encrypt */
#define AES_FLAG_DECRYPT 2 /** Decrypt */
/**
* Encrypt/decrypt data using AES (ECB mode, no padding).
*
* @key: Key material for initialisation.
* @key_len: Length of @key in bytes. Must be an AES_KEY_LEN_ constant.
* @bytes_in: Bytes to encrypt/decrypt.
* @len_in: Length of @bytes_in in bytes. Must be a multiple of @AES_BLOCK_LEN.
* @flags: AES_FLAG_ constants indicating the desired behaviour.
* @bytes_out: Destination for the encrypted/decrypted data.
* @len: The length of @bytes_out in bytes. Must be a multiple of @AES_BLOCK_LEN.
*/
WALLY_CORE_API int wally_aes(
const unsigned char *key,
size_t key_len,
const unsigned char *bytes_in,
size_t len_in,
uint32_t flags,
unsigned char *bytes_out,
size_t len);
/**
* Encrypt/decrypt data using AES (CBC mode).
*
* @key: Key material for initialisation.
* @key_len: Length of @key in bytes. Must be an AES_KEY_LEN_ constant.
* @iv: Initialisation vector.
* @iv_len: Length of @iv in bytes. Must be @AES_BLOCK_LEN.
* @bytes_in: Bytes to encrypt/decrypt.
* @len_in: Length of @bytes_in in bytes. Must be a multiple of @AES_BLOCK_LEN.
* @flags: AES_FLAG_ constants indicating the desired behaviour.
* @bytes_out: Destination for the encrypted/decrypted data.
* @len: The length of @bytes_out in bytes. Must be a multiple of @AES_BLOCK_LEN.
* @written: Destination for the number of bytes written to @bytes_out.
*
* Defaults to PKCS#7 padding.
*/
WALLY_CORE_API int wally_aes_cbc(
const unsigned char *key,
size_t key_len,
const unsigned char *iv,
size_t iv_len,
const unsigned char *bytes_in,
size_t len_in,
uint32_t flags,
unsigned char *bytes_out,
size_t len,
size_t *written);
/** Output length for @wally_sha256 */
#define SHA256_LEN 32
/** Output length for @wally_sha512 */
#define SHA512_LEN 64
/**
* SHA-256(m)
*
* @bytes_in: The message to hash
* @len_in: The length of @bytes_in in bytes.
* @bytes_out: Destination for the resulting hash.
* @len: The length of @bytes_out in bytes. Must be @SHA256_LEN.
*/
WALLY_CORE_API int wally_sha256(
const unsigned char *bytes_in,
size_t len_in,
unsigned char *bytes_out,
size_t len);
/**
* SHA-256(SHA-256(m)) (double SHA-256)
*
* @bytes_in: The message to hash
* @len_in: The length of @bytes_in in bytes.
* @bytes_out: Destination for the resulting hash.
* @len: The length of @bytes_out in bytes. Must be @SHA256_LEN.
*/
WALLY_CORE_API int wally_sha256d(
const unsigned char *bytes_in,
size_t len_in,
unsigned char *bytes_out,
size_t len);
/**
* SHA-512(m)
*
* @bytes_in: The message to hash
* @len_in: The length of @bytes_in in bytes.
* @bytes_out: Destination for the resulting hash.
* @len: The length of @bytes_out in bytes. Must be @SHA512_LEN.
*/
WALLY_CORE_API int wally_sha512(
const unsigned char *bytes_in,
size_t len_in,
unsigned char *bytes_out,
size_t len);
/** Output length for @wally_hash160 */
#define HASH160_LEN 20
/**
* RIPEMD-160(SHA-256(m))
*
* @bytes_in: The message to hash
* @len_in: The length of @bytes_in in bytes.
* @bytes_out: Destination for the resulting hash.
* @len: The length of @bytes_out in bytes. Must be @HASH160_LEN.
*/
WALLY_CORE_API int wally_hash160(
const unsigned char *bytes_in,
size_t len_in,
unsigned char *bytes_out,
size_t len);
/** Output length for @wally_hmac_sha256 */
#define HMAC_SHA256_LEN 32
/** Output length for @wally_hmac_sha512 */
#define HMAC_SHA512_LEN 64
/**
* Compute an HMAC using SHA-256
*
* @key: The key for the hash
* @key_len: The length of @key in bytes.
* @bytes_in: The message to hash
* @len_in: The length of @bytes_in in bytes.
* @bytes_out: Destination for the resulting HMAC.
* @len: The length of @bytes_out in bytes. Must be @HMAC_SHA256_LEN.
*/
WALLY_CORE_API int wally_hmac_sha256(
const unsigned char *key,
size_t key_len,
const unsigned char *bytes_in,
size_t len_in,
unsigned char *bytes_out,
size_t len);
/**
* Compute an HMAC using SHA-512
*
* @key: The key for the hash
* @key_len: The length of @key in bytes.
* @bytes_in: The message to hash
* @len_in: The length of @bytes_in in bytes.
* @bytes_out: Destination for the resulting HMAC.
* @len: The length of @bytes_out in bytes. Must be @HMAC_SHA512_LEN.
*/
WALLY_CORE_API int wally_hmac_sha512(
const unsigned char *key,
size_t key_len,
const unsigned char *bytes_in,
size_t len_in,
unsigned char *bytes_out,
size_t len);
/** Extra bytes required at the end of 'salt_in_out' for pbkdf2 functions */
#define PBKDF2_HMAC_EXTRA_LEN 4
/** Output length for @wally_pbkdf2_hmac_sha256 */
#define PBKDF2_HMAC_SHA256_LEN 32
/** Output length for @wally_pbkdf2_hmac_sha512 */
#define PBKDF2_HMAC_SHA512_LEN 64
/** For hmac functions, indicates that 'salt_in_out' contains
* @PBKDF2_HMAC_EXTRA_LEN extra bytes for the block number to be added into.
*/
#define PBKDF2_HMAC_FLAG_BLOCK_RESERVED 1
/**
* Derive a pseudorandom key from inputs using HMAC SHA-256.
*
* @pass: Password to derive from.
* @pass_len: Length of @pass in bytes.
* @salt_in_out: Salt to derive from. If @flags contains the value
* @PBKDF2_HMAC_FLAG_BLOCK_RESERVED then this memory must
* have @PBKDF2_HMAC_EXTRA_LEN of spare room at the end of the salt itself.
* @salt_len: Length of @salt_in_out in bytes, including any extra spare bytes.
* @flags: PBKDF2_HMAC_FLAG_ flag values indicating desired behaviour.
* @cost: The cost of the function. The larger this number, the
* longer the key will take to derive.
* @bytes_out: Destination for the derived pseudorandom key.
* @len: The length of @bytes_out in bytes. This must be a multiple
* of @PBKDF2_HMAC_SHA256_LEN.
*
* Returns 0 on success or non-zero if any parameter is invalid.
*/
WALLY_CORE_API int wally_pbkdf2_hmac_sha256(
const unsigned char *pass,
size_t pass_len,
unsigned char *salt_in_out,
size_t salt_len,
uint32_t flags,
uint32_t cost,
unsigned char *bytes_out,
size_t len);
/**
* Derive a pseudorandom key from inputs using HMAC SHA-512.
*
* @pass: Password to derive from.
* @pass_len: Length of @pass in bytes.
* @salt_in_out: Salt to derive from. If @flags contains the value
* @PBKDF2_HMAC_FLAG_BLOCK_RESERVED then this memory must
* have @PBKDF2_HMAC_EXTRA_LEN of spare room at the end of the salt itself.
* @salt_len: Length of @salt_in_out in bytes, including any extra spare bytes.
* @flags: PBKDF2_HMAC_FLAG_ flag values indicating desired behaviour.
* @cost: The cost of the function. The larger this number, the
* longer the key will take to derive.
* @bytes_out: Destination for the derived pseudorandom key.
* @len: The length of @bytes_out in bytes. This must be a multiple
* of @PBKDF2_HMAC_SHA512_LEN.
*
* Returns 0 on success or non-zero if any parameter is invalid.
*/
WALLY_CORE_API int wally_pbkdf2_hmac_sha512(
const unsigned char *pass,
size_t pass_len,
unsigned char *salt_in_out,
size_t salt_len,
uint32_t flags,
uint32_t cost,
unsigned char *bytes_out,
size_t len);
/** The length of a private key used for EC signing */
#define EC_PRIVATE_KEY_LEN 32
/** The length of a public key used for EC signing */
#define EC_PUBLIC_KEY_LEN 33
/** The length of an uncompressed public key */
#define EC_PUBLIC_KEY_UNCOMPRESSED_LEN 65
/** The length of a message hash to EC sign */
#define EC_MESSAGE_HASH_LEN 32
/** The length of a compact signature produced by EC signing */
#define EC_SIGNATURE_LEN 64
/** The maximum encoded length of a DER encoded signature */
#define EC_SIGNATURE_DER_MAX_LEN 72
/** Indicates that a signature using ECDSA/secp256k1 is required */
#define EC_FLAG_ECDSA 0x1
/** Indicates that a signature using EC-Schnorr-SHA256 is required */
#define EC_FLAG_SCHNORR 0x2
/**
* Verify that a private key is valid.
*
* @priv_key: The private key to validate.
* @priv_key_len: The length of @priv_key in bytes. Must be @EC_PRIVATE_KEY_LEN.
*/
WALLY_CORE_API int wally_ec_private_key_verify(
const unsigned char *priv_key,
size_t priv_key_len);
/**
* Create a public key from a private key.
*
* @priv_key: The private key to create a public key from.
* @priv_key_len: The length of @priv_key in bytes. Must be @EC_PRIVATE_KEY_LEN.
* @bytes_out: Destination for the resulting public key.
* @len: The length of @bytes_out in bytes. Must be @EC_PUBLIC_KEY_LEN.
*/
WALLY_CORE_API int wally_ec_public_key_from_private_key(
const unsigned char *priv_key,
size_t priv_key_len,
unsigned char *bytes_out,
size_t len);
/**
* Create an uncompressed public key from a compressed public key.
*
* @pub_key: The private key to create a public key from.
* @pub_key_len: The length of @pub_key in bytes. Must be @EC_PUBLIC_KEY_LEN.
* @bytes_out: Destination for the resulting public key.
* @len: The length of @bytes_out in bytes. Must be @EC_PUBLIC_KEY_UNCOMPRESSED_LEN.
*/
WALLY_CORE_API int wally_ec_public_key_decompress(
const unsigned char *pub_key,
size_t pub_key_len,
unsigned char *bytes_out,
size_t len);
/**
* Sign a message hash with a private key, producing a compact signature.
*
* @priv_key: The private key to sign with.
* @priv_key_len: The length of @priv_key in bytes. Must be @EC_PRIVATE_KEY_LEN.
* @bytes_in: The message hash to sign.
* @len_in: The length of @bytes_in in bytes. Must be @EC_MESSAGE_HASH_LEN.
* @flags: EC_FLAG_ flag values indicating desired behaviour.
* @bytes_out: Destination for the resulting compact signature.
* @len: The length of @bytes_out in bytes. Must be @EC_SIGNATURE_LEN.
*/
WALLY_CORE_API int wally_ec_sig_from_bytes(
const unsigned char *priv_key,
size_t priv_key_len,
const unsigned char *bytes_in,
size_t len_in,
uint32_t flags,
unsigned char *bytes_out,
size_t len);
/**
* Convert a signature to low-s form.
*
* @sig_in: The compact signature to convert.
* @sig_in_len: The length of @sig_in in bytes. Must be @EC_SIGNATURE_LEN.
* @bytes_out: Destination for the resulting low-s signature.
* @len: The length of @bytes_out in bytes. Must be @EC_SIGNATURE_LEN.
*/
WALLY_CORE_API int wally_ec_sig_normalize(
const unsigned char *sig_in,
size_t sig_in_len,
unsigned char *bytes_out,
size_t len);
/**
* Convert a compact signature to DER encoding.
*
* @sig_in: The compact signature to convert.
* @sig_in_len: The length of @sig_in in bytes. Must be @EC_SIGNATURE_LEN.
* @bytes_out: Destination for the resulting DER encoded signature.
* @len: The length of @bytes_out in bytes. Must be @EC_SIGNATURE_DER_MAX_LEN.
* @written: Destination for the number of bytes written to @bytes_out.
*/
WALLY_CORE_API int wally_ec_sig_to_der(
const unsigned char *sig_in,
size_t sig_in_len,
unsigned char *bytes_out,
size_t len,
size_t *written);
/**
* Convert a DER encoded signature to a compact signature.
*
* @bytes_in: The DER encoded signature to convert.
* @len_in: The length of @sig_in in bytes.
* @bytes_out: Destination for the resulting compact signature.
* @len: The length of @bytes_out in bytes. Must be @EC_SIGNATURE_LEN.
*/
WALLY_CORE_API int wally_ec_sig_from_der(
const unsigned char *bytes_in,
size_t len_in,
unsigned char *bytes_out,
size_t len);
/**
* Verify a signed message hash.
*
* @pub_key: The public key to verify with.
* @pub_key_len: The length of @pub_key in bytes. Must be @EC_PUBLIC_KEY_LEN.
* @bytes_in: The message hash to verify.
* @len_in: The length of @bytes_in in bytes. Must be @EC_MESSAGE_HASH_LEN.
* @flags: EC_FLAG_ flag values indicating desired behaviour.
* @sig_in: The compact signature of the message in @bytes_in.
* @sig_in_len: The length of @sig_in in bytes. Must be @EC_SIGNATURE_LEN.
*/
WALLY_CORE_API int wally_ec_sig_verify(
const unsigned char *pub_key,
size_t pub_key_len,
const unsigned char *bytes_in,
size_t len_in,
uint32_t flags,
const unsigned char *sig_in,
size_t sig_in_len);
/** The maximim size of input message that can be formatted */
#define BITCOIN_MESSAGE_MAX_LEN (64 * 1024 - 64)
/** Indicates that SHA256D(message) should be returned */
#define BITCOIN_MESSAGE_FLAG_HASH 1
/**
* Format a message for use as a bitcoin signed message.
*
* @bytes_in: The message string to sign.
* @len_in: The length of @bytes_in in bytes. Must be less than
* or equal to BITCOIN_MESSAGE_MAX_LEN.
* @flags: BITCOIN_MESSAGE_FLAG_ flags indicating the desired output.
* if BITCOIN_MESSAGE_FLAG_HASH is passed, the double SHA256 hash
* of the message is placed in @bytes_out instead of the formatted
* message. In this case @len must be at least @SHA256_LEN.
* @bytes_out: Destination for the formatted message or message hash.
* @len: The length of @bytes_out in bytes.
* @written: Destination for the number of bytes written to @bytes_out.
*/
WALLY_CORE_API int wally_format_bitcoin_message(const unsigned char *bytes_in,
size_t len_in,
uint32_t flags,
unsigned char *bytes_out,
size_t len,
size_t *written);
#endif /* LIBWALLY_CORE_CRYPTO_H */