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
443 lines
14 KiB
8 years ago
|
#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 */
|