mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-05 02:33:07 +02:00
Squashed 'src/secp256k1/' changes from 22f60a6..2bfb82b
2bfb82bMerge pull request #35106aeea5Turn secp256k1_ec_pubkey_serialize outlen to in/out970164dMerge pull request #3486466625Improvements for coordinate decompressione2100adMerge pull request #3478e48787Change secp256k1_ec_pubkey_combine's count argument to size_t.c69dea0Clear output in more cases for pubkey_combine, adds tests.269d422Comment copyediting.b4d17daMerge pull request #3444709265Merge pull request #34526abce7Adds 32 static test vectors for scalar mul, sqr, inv.5b71a3fBetter error case handling for pubkey_create & pubkey_serialize, more tests.3b7bc69Merge pull request #343eed87afChange contrib/laxder from headers-only to files compilable as standalone Cd7eb1aeMerge pull request #3427914a6eMake lax_der_privatekey_parsing.h not depend on internal code73f64ffMerge pull request #3399234391Overhaul flags handling1a36898Make flags more explicit, add runtime checks.1a3e03aMerge pull request #34096be204Add additional tests for eckey and arg-checks.bb5aa4dMake the tweak function zeroize-output-on-fail behavior consistent.4a243daMove secp256k1_ec_privkey_import/export to contrib.1b3efc1Move secp256k1_ecdsa_sig_recover into the recovery module.e3cd679Eliminate all side-effects from VERIFY_CHECK() usage.b30fc85Avoid nonce_function_rfc6979 algo16 argument emulation.70d4640Make secp256k1_ec_pubkey_create skip processing invalid secret keys.6c476a8Minor comment improvements.131afe5Merge pull request #3340c6ab2fIntroduce explicit lower-S normalizationfea19e7Add contrib/lax_der_parsing.h3bb9c44Rewrite ECDSA signature parsing codefa57f1bUse secp256k1_rand_int and secp256k1_rand_bits more49b3749Add new tests for the extra testrand functionsf684d7dFaster secp256k1_rand_int implementation251b1a6Improve testrand: add extra random functions31994c8Merge pull request #338f79aa88Bugfix: swap arguments to noncefpc98df26Merge pull request #31967f7da4Extensive interface and operations tests for secp256k1_ec_pubkey_parse.ee2cb40Add ARG_CHECKs to secp256k1_ec_pubkey_parse/secp256k1_ec_pubkey_serialize7450ef1Merge pull request #32868a3c76Merge pull request #32998135eeMerge pull request #33237100d7improve ECDH header-docb13d749Fix couple of typos in API comments7c823e3travis: fixup module configscc3141aMerge pull request #325ee58faeMerge pull request #326213aa67Do not force benchmarks to be statically linked.338fc8bAdd API exports to secp256k1_nonce_function_default and secp256k1_nonce_function_rfc6979.52fd03fMerge pull request #3209f6993fRemove some dead code.357f8cdMerge pull request #314118cd82Use explicit symbol visibility.4e64608Include public module headers when compiling modules.1f41437Merge pull request #316fe0d463Merge pull request #317cfe0ed9Fix miscellaneous style nits that irritate overactive static analysis.2b199deUse the explicit NULL macro for pointer comparisons.9e90516Merge pull request #294dd891e0Get rid of _t as it is POSIX reserved201819bMerge pull request #313912f203Eliminate a few unbraced statements that crept into the code.eeab823Merge pull request #299486b9bbUse a flags bitfield for compressed option to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export05732c5Callback data: Accept pointers to either const or non-const data1973c73Bugfix: Reinitialise buffer lengths that have been used as outputs788038dUse size_t for lengths (at least in external API)c9d7c2asecp256k1_context_set_{error,illegal}_callback: Restore default handler by passing NULL as function argument9aac008secp256k1_context_destroy: Allow NULL argument as a no-op64b730bsecp256k1_context_create: Use unsigned type for flags bitfieldcb04ab5Merge pull request #309a551669Merge pull request #29581e45ffUpdate group_impl.h85e3a2cMerge pull request #112b2eb63bMerge pull request #293dc0ce9f[API BREAK] Change argument order to out/outin/in6d947caMerge pull request #298c822693Merge pull request #3016d04350Merge pull request #3037ab311cMerge pull request #3045fb3229Fixes a bug where bench_sign would fail due to passing in too small a buffer.263dcbcremove unused assignmentb183b41bugfix: "ARG_CHECK(ctx != NULL)" makes no sense6da1446build: fix parallel build5eb4356Merge pull request #291c996d53Print success9f443beMove pubkey recovery code to separate moduled49abbdSeparate ECDSA recovery tests439d34aSeparate recoverable and normal signaturesa7b046eMerge pull request #289f66907fImprove/reformat API documentation secp256k1.h2f77487Add context building benchmarkscc623d5Merge pull request #287de7e398small typo fix9d96e36Merge pull request #280432e1ceMerge pull request #28314727fdUse correct name in gitignore356b0e9Actually test static precomputation in Travisff3a5dfMerge pull request #2842587208Merge pull request #212a5a66c7Add support for custom EC-Schnorr-SHA256 signaturesd84a378Merge pull request #25272ae443Improve perf. of cmov-based table lookup92e53fcImplement endomorphism optimization for secp256k1_ecmult_consted35d43Make `secp256k1_scalar_add_bit` conditional; make `secp256k1_scalar_split_lambda_var` constant time91c0ce9Add benchmarks for ECDH and const-time multiplication0739bbbAdd ECDH module which works by hashing the output of ecmult_const4401500Add constant-time multiply `secp256k1_ecmult_const` for ECDHe4ce393build: fix hard-coded usage of "gen_context"b8e39acbuild: don't use BUILT_SOURCES for the static context headerbaa75datests: add a couple testsae4f0c6Merge pull request #278995c548Introduce callback functions for dealing with errors.c333074Merge pull request #28218c329cRemove the internal secp256k1_ecdsa_sig_t type74a2acdAdd a secp256k1_ecdsa_signature_t type23cfa91Introduce secp256k1_pubkey_t type4c63780Merge pull request #2693e6f1e2Change rfc6979 implementation to be a generic PRNGed5334aUpdate configure.ac to make it build on OpenBSD1b68366Merge pull request #274a83bb48Make ecmult static precomputation default166b32fMerge pull request #276c37812fAdd gen_context src/ecmult_static_context.h to CLEANFILES to fix distclean.125c15dMerge pull request #27576f6769Fix build with static ecmult altroot and make dist.5133f78Merge pull request #254b0a60e6Merge pull request #258733c1e6Add travis build to test the static context.fbecc38Add ability to use a statically generated ecmult context.4fb174dMerge pull request #263 4ab8990 Merge pull request #270bdf0e0cMerge pull request #27131d0c1fMerge pull request #273eb2c8ffAdd missing casts to SECP256K1_FE_CONST_INNER55399c2Further performance improvements to _ecmult_wnaf99fd963Add secp256k1_ec_pubkey_compress(), with test similar to the related decompress() function.145cc6eImprove performance of _ecmult_wnaf36b305aVerify the result of GMP modular inverse using non-GMP code0cbc860Merge pull request #26606ff7feMerge pull request #2675a43124Save 1 _fe_negate since s1 == -s2a5d796eUpdate code comments3f3964eAdd specific VERIFY tests for _fe_cmov7d054cdRefactor to save a _fe_negateb28d02aRefactor to remove a local var55e7fc3Perf. improvement in _gej_add_gea0601cdFix VERIFY calculations in _fe_cmov methods17f7148Merge pull request #2617657420Add tests for adding P+Q with P.x!=Q.x and P.y=-Q.y8c5d5f7tests: Add failing unit test for #257 (bad addition formula)5de4c5dgej_add_ge: fix degenerate case when computing P + (-lambda)Pbcf2fcfgej_add_ge: rearrange algebrae2a07c7Fix compilation with C++873a453Merge pull request #25091eb0daMerge pull request #247210ffedUse separate in and out pointers in `secp256k1_ec_pubkey_decompress`a1d5ae1Tiny optimization729badfMerge pull request #2102d5a186Apply effective-affine trick to precomp4f9791aEffective affine addition in EC multiplication2b4cf41Use pkg-config always when possible, with failover to manual checks for libcrypto git-subtree-dir: src/secp256k1 git-subtree-split:2bfb82b10e
This commit is contained in:
@@ -5,6 +5,99 @@
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* These rules specify the order of arguments in API calls:
|
||||
*
|
||||
* 1. Context pointers go first, followed by output arguments, combined
|
||||
* output/input arguments, and finally input-only arguments.
|
||||
* 2. Array lengths always immediately the follow the argument whose length
|
||||
* they describe, even if this violates rule 1.
|
||||
* 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated
|
||||
* later go first. This means: signatures, public nonces, private nonces,
|
||||
* messages, public keys, secret keys, tweaks.
|
||||
* 4. Arguments that are not data pointers go last, from more complex to less
|
||||
* complex: function pointers, algorithm names, messages, void pointers,
|
||||
* counts, flags, booleans.
|
||||
* 5. Opaque data pointers follow the function pointer they are to be passed to.
|
||||
*/
|
||||
|
||||
/** Opaque data structure that holds context information (precomputed tables etc.).
|
||||
*
|
||||
* The purpose of context structures is to cache large precomputed data tables
|
||||
* that are expensive to construct, and also to maintain the randomization data
|
||||
* for blinding.
|
||||
*
|
||||
* Do not create a new context object for each operation, as construction is
|
||||
* far slower than all other API calls (~100 times slower than an ECDSA
|
||||
* verification).
|
||||
*
|
||||
* A constructed context can safely be used from multiple threads
|
||||
* simultaneously, but API call that take a non-const pointer to a context
|
||||
* need exclusive access to it. In particular this is the case for
|
||||
* secp256k1_context_destroy and secp256k1_context_randomize.
|
||||
*
|
||||
* Regarding randomization, either do it once at creation time (in which case
|
||||
* you do not need any locking for the other calls), or use a read-write lock.
|
||||
*/
|
||||
typedef struct secp256k1_context_struct secp256k1_context;
|
||||
|
||||
/** Opaque data structure that holds a parsed and valid public key.
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
* guaranteed to be portable between different platforms or versions. It is
|
||||
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
|
||||
* If you need to convert to a format suitable for storage or transmission, use
|
||||
* secp256k1_ec_pubkey_serialize and secp256k1_ec_pubkey_parse.
|
||||
*
|
||||
* Furthermore, it is guaranteed that identical public keys (ignoring
|
||||
* compression) will have identical representation, so they can be memcmp'ed.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char data[64];
|
||||
} secp256k1_pubkey;
|
||||
|
||||
/** Opaque data structured that holds a parsed ECDSA signature.
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
* guaranteed to be portable between different platforms or versions. It is
|
||||
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
|
||||
* If you need to convert to a format suitable for storage or transmission, use
|
||||
* the secp256k1_ecdsa_signature_serialize_* and
|
||||
* secp256k1_ecdsa_signature_serialize_* functions.
|
||||
*
|
||||
* Furthermore, it is guaranteed to identical signatures will have identical
|
||||
* representation, so they can be memcmp'ed.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char data[64];
|
||||
} secp256k1_ecdsa_signature;
|
||||
|
||||
/** A pointer to a function to deterministically generate a nonce.
|
||||
*
|
||||
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
|
||||
* Out: nonce32: pointer to a 32-byte array to be filled by the function.
|
||||
* In: msg32: the 32-byte message hash being verified (will not be NULL)
|
||||
* key32: pointer to a 32-byte secret key (will not be NULL)
|
||||
* algo16: pointer to a 16-byte array describing the signature
|
||||
* algorithm (will be NULL for ECDSA for compatibility).
|
||||
* data: Arbitrary data pointer that is passed through.
|
||||
* attempt: how many iterations we have tried to find a nonce.
|
||||
* This will almost always be 0, but different attempt values
|
||||
* are required to result in a different nonce.
|
||||
*
|
||||
* Except for test cases, this function should compute some cryptographic hash of
|
||||
* the message, the algorithm, the key and the attempt.
|
||||
*/
|
||||
typedef int (*secp256k1_nonce_function)(
|
||||
unsigned char *nonce32,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *key32,
|
||||
const unsigned char *algo16,
|
||||
void *data,
|
||||
unsigned int attempt
|
||||
);
|
||||
|
||||
# if !defined(SECP256K1_GNUC_PREREQ)
|
||||
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
|
||||
# define SECP256K1_GNUC_PREREQ(_maj,_min) \
|
||||
@@ -26,6 +119,20 @@ extern "C" {
|
||||
# define SECP256K1_INLINE inline
|
||||
# endif
|
||||
|
||||
#ifndef SECP256K1_API
|
||||
# if defined(_WIN32)
|
||||
# ifdef SECP256K1_BUILD
|
||||
# define SECP256K1_API __declspec(dllexport)
|
||||
# else
|
||||
# define SECP256K1_API
|
||||
# endif
|
||||
# elif defined(__GNUC__) && defined(SECP256K1_BUILD)
|
||||
# define SECP256K1_API __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define SECP256K1_API
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**Warning attributes
|
||||
* NONNULL is not used if SECP256K1_BUILD is set to avoid the compiler optimizing out
|
||||
* some paranoid null checks. */
|
||||
@@ -40,305 +147,434 @@ extern "C" {
|
||||
# define SECP256K1_ARG_NONNULL(_x)
|
||||
# endif
|
||||
|
||||
/** Opaque data structure that holds context information (precomputed tables etc.).
|
||||
* Only functions that take a pointer to a non-const context require exclusive
|
||||
* access to it. Multiple functions that take a pointer to a const context may
|
||||
* run simultaneously.
|
||||
*/
|
||||
typedef struct secp256k1_context_struct secp256k1_context_t;
|
||||
/** All flags' lower 8 bits indicate what they're for. Do not use directly. */
|
||||
#define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1)
|
||||
#define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0)
|
||||
#define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1)
|
||||
/** The higher bits contain the actual data. Do not use directly. */
|
||||
#define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8)
|
||||
#define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9)
|
||||
#define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8)
|
||||
|
||||
/** Flags to pass to secp256k1_context_create. */
|
||||
# define SECP256K1_CONTEXT_VERIFY (1 << 0)
|
||||
# define SECP256K1_CONTEXT_SIGN (1 << 1)
|
||||
#define SECP256K1_CONTEXT_VERIFY (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_VERIFY)
|
||||
#define SECP256K1_CONTEXT_SIGN (SECP256K1_FLAGS_TYPE_CONTEXT | SECP256K1_FLAGS_BIT_CONTEXT_SIGN)
|
||||
#define SECP256K1_CONTEXT_NONE (SECP256K1_FLAGS_TYPE_CONTEXT)
|
||||
|
||||
/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */
|
||||
#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION)
|
||||
#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION)
|
||||
|
||||
/** Create a secp256k1 context object.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
* In: flags: which parts of the context to initialize.
|
||||
*/
|
||||
secp256k1_context_t* secp256k1_context_create(
|
||||
int flags
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_create(
|
||||
unsigned int flags
|
||||
) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Copies a secp256k1 context object.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
* In: ctx: an existing context to copy
|
||||
* Args: ctx: an existing context to copy (cannot be NULL)
|
||||
*/
|
||||
secp256k1_context_t* secp256k1_context_clone(
|
||||
const secp256k1_context_t* ctx
|
||||
) SECP256K1_WARN_UNUSED_RESULT;
|
||||
SECP256K1_API secp256k1_context* secp256k1_context_clone(
|
||||
const secp256k1_context* ctx
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Destroy a secp256k1 context object.
|
||||
*
|
||||
* The context pointer may not be used afterwards.
|
||||
* Args: ctx: an existing context to destroy (cannot be NULL)
|
||||
*/
|
||||
void secp256k1_context_destroy(
|
||||
secp256k1_context_t* ctx
|
||||
SECP256K1_API void secp256k1_context_destroy(
|
||||
secp256k1_context* ctx
|
||||
);
|
||||
|
||||
/** Set a callback function to be called when an illegal argument is passed to
|
||||
* an API call. It will only trigger for violations that are mentioned
|
||||
* explicitly in the header.
|
||||
*
|
||||
* The philosophy is that these shouldn't be dealt with through a
|
||||
* specific return value, as calling code should not have branches to deal with
|
||||
* the case that this code itself is broken.
|
||||
*
|
||||
* On the other hand, during debug stage, one would want to be informed about
|
||||
* such mistakes, and the default (crashing) may be inadvisable.
|
||||
* When this callback is triggered, the API function called is guaranteed not
|
||||
* to cause a crash, though its return value and output arguments are
|
||||
* undefined.
|
||||
*
|
||||
* Args: ctx: an existing context object (cannot be NULL)
|
||||
* In: fun: a pointer to a function to call when an illegal argument is
|
||||
* passed to the API, taking a message and an opaque pointer
|
||||
* (NULL restores a default handler that calls abort).
|
||||
* data: the opaque pointer to pass to fun above.
|
||||
*/
|
||||
SECP256K1_API void secp256k1_context_set_illegal_callback(
|
||||
secp256k1_context* ctx,
|
||||
void (*fun)(const char* message, void* data),
|
||||
const void* data
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** Verify an ECDSA signature.
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: invalid public key
|
||||
* -2: invalid signature
|
||||
* In: ctx: a secp256k1 context object, initialized for verification.
|
||||
* msg32: the 32-byte message hash being verified (cannot be NULL)
|
||||
* sig: the signature being verified (cannot be NULL)
|
||||
* siglen: the length of the signature
|
||||
* pubkey: the public key to verify with (cannot be NULL)
|
||||
* pubkeylen: the length of pubkey
|
||||
/** Set a callback function to be called when an internal consistency check
|
||||
* fails. The default is crashing.
|
||||
*
|
||||
* This can only trigger in case of a hardware failure, miscompilation,
|
||||
* memory corruption, serious bug in the library, or other error would can
|
||||
* otherwise result in undefined behaviour. It will not trigger due to mere
|
||||
* incorrect usage of the API (see secp256k1_context_set_illegal_callback
|
||||
* for that). After this callback returns, anything may happen, including
|
||||
* crashing.
|
||||
*
|
||||
* Args: ctx: an existing context object (cannot be NULL)
|
||||
* In: fun: a pointer to a function to call when an internal error occurs,
|
||||
* taking a message and an opaque pointer (NULL restores a default
|
||||
* handler that calls abort).
|
||||
* data: the opaque pointer to pass to fun above.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *sig,
|
||||
int siglen,
|
||||
const unsigned char *pubkey,
|
||||
int pubkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
|
||||
SECP256K1_API void secp256k1_context_set_error_callback(
|
||||
secp256k1_context* ctx,
|
||||
void (*fun)(const char* message, void* data),
|
||||
const void* data
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** A pointer to a function to deterministically generate a nonce.
|
||||
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
|
||||
* In: msg32: the 32-byte message hash being verified (will not be NULL)
|
||||
* key32: pointer to a 32-byte secret key (will not be NULL)
|
||||
* attempt: how many iterations we have tried to find a nonce.
|
||||
* This will almost always be 0, but different attempt values
|
||||
* are required to result in a different nonce.
|
||||
* data: Arbitrary data pointer that is passed through.
|
||||
* Out: nonce32: pointer to a 32-byte array to be filled by the function.
|
||||
* Except for test cases, this function should compute some cryptographic hash of
|
||||
* the message, the key and the attempt.
|
||||
/** Parse a variable-length public key into the pubkey object.
|
||||
*
|
||||
* Returns: 1 if the public key was fully valid.
|
||||
* 0 if the public key could not be parsed or is invalid.
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
|
||||
* parsed version of input. If not, its value is undefined.
|
||||
* In: input: pointer to a serialized public key
|
||||
* inputlen: length of the array pointed to by input
|
||||
*
|
||||
* This function supports parsing compressed (33 bytes, header byte 0x02 or
|
||||
* 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header
|
||||
* byte 0x06 or 0x07) format public keys.
|
||||
*/
|
||||
typedef int (*secp256k1_nonce_function_t)(
|
||||
unsigned char *nonce32,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *key32,
|
||||
unsigned int attempt,
|
||||
const void *data
|
||||
);
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey* pubkey,
|
||||
const unsigned char *input,
|
||||
size_t inputlen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize a pubkey object into a serialized byte sequence.
|
||||
*
|
||||
* Returns: 1 always.
|
||||
* Args: ctx: a secp256k1 context object.
|
||||
* Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if
|
||||
* compressed==1) byte array to place the serialized key
|
||||
* in.
|
||||
* In/Out: outputlen: a pointer to an integer which is initially set to the
|
||||
* size of output, and is overwritten with the written
|
||||
* size.
|
||||
* In: pubkey: a pointer to a secp256k1_pubkey containing an
|
||||
* initialized public key.
|
||||
* flags: SECP256K1_EC_COMPRESSED if serialization should be in
|
||||
* compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ec_pubkey_serialize(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *output,
|
||||
size_t *outputlen,
|
||||
const secp256k1_pubkey* pubkey,
|
||||
unsigned int flags
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Parse an ECDSA signature in compact (64 bytes) format.
|
||||
*
|
||||
* Returns: 1 when the signature could be parsed, 0 otherwise.
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: sig: a pointer to a signature object
|
||||
* In: input64: a pointer to the 64-byte array to parse
|
||||
*
|
||||
* The signature must consist of a 32-byte big endian R value, followed by a
|
||||
* 32-byte big endian S value. If R or S fall outside of [0..order-1], the
|
||||
* encoding is invalid. R and S with value 0 are allowed in the encoding.
|
||||
*
|
||||
* After the call, sig will always be initialized. If parsing failed or R or
|
||||
* S are zero, the resulting sig value is guaranteed to fail validation for any
|
||||
* message and public key.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const unsigned char *input64
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Parse a DER ECDSA signature.
|
||||
*
|
||||
* Returns: 1 when the signature could be parsed, 0 otherwise.
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: sig: a pointer to a signature object
|
||||
* In: input: a pointer to the signature to be parsed
|
||||
* inputlen: the length of the array pointed to be input
|
||||
*
|
||||
* This function will accept any valid DER encoded signature, even if the
|
||||
* encoded numbers are out of range.
|
||||
*
|
||||
* After the call, sig will always be initialized. If parsing failed or the
|
||||
* encoded numbers are out of range, signature validation with it is
|
||||
* guaranteed to fail for every message and public key.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_parse_der(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const unsigned char *input,
|
||||
size_t inputlen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize an ECDSA signature in DER format.
|
||||
*
|
||||
* Returns: 1 if enough space was available to serialize, 0 otherwise
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: output: a pointer to an array to store the DER serialization
|
||||
* In/Out: outputlen: a pointer to a length integer. Initially, this integer
|
||||
* should be set to the length of output. After the call
|
||||
* it will be set to the length of the serialization (even
|
||||
* if 0 was returned).
|
||||
* In: sig: a pointer to an initialized signature object
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *output,
|
||||
size_t *outputlen,
|
||||
const secp256k1_ecdsa_signature* sig
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Serialize an ECDSA signature in compact (64 byte) format.
|
||||
*
|
||||
* Returns: 1
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: output64: a pointer to a 64-byte array to store the compact serialization
|
||||
* In: sig: a pointer to an initialized signature object
|
||||
*
|
||||
* See secp256k1_ecdsa_signature_parse_compact for details about the encoding.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *output64,
|
||||
const secp256k1_ecdsa_signature* sig
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Verify an ECDSA signature.
|
||||
*
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect or unparseable signature
|
||||
* Args: ctx: a secp256k1 context object, initialized for verification.
|
||||
* In: sig: the signature being verified (cannot be NULL)
|
||||
* msg32: the 32-byte message hash being verified (cannot be NULL)
|
||||
* pubkey: pointer to an initialized public key to verify with (cannot be NULL)
|
||||
*
|
||||
* To avoid accepting malleable signatures, only ECDSA signatures in lower-S
|
||||
* form are accepted.
|
||||
*
|
||||
* If you need to accept ECDSA signatures from sources that do not obey this
|
||||
* rule, apply secp256k1_ecdsa_signature_normalize to the signature prior to
|
||||
* validation, but be aware that doing so results in malleable signatures.
|
||||
*
|
||||
* For details, see the comments for that function.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
|
||||
const secp256k1_context* ctx,
|
||||
const secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_pubkey *pubkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Convert a signature to a normalized lower-S form.
|
||||
*
|
||||
* Returns: 1 if sigin was not normalized, 0 if it already was.
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: sigout: a pointer to a signature to fill with the normalized form,
|
||||
* or copy if the input was already normalized. (can be NULL if
|
||||
* you're only interested in whether the input was already
|
||||
* normalized).
|
||||
* In: sigin: a pointer to a signature to check/normalize (cannot be NULL,
|
||||
* can be identical to sigout)
|
||||
*
|
||||
* With ECDSA a third-party can forge a second distinct signature of the same
|
||||
* message, given a single initial signature, but without knowing the key. This
|
||||
* is done by negating the S value modulo the order of the curve, 'flipping'
|
||||
* the sign of the random point R which is not included in the signature.
|
||||
*
|
||||
* Forgery of the same message isn't universally problematic, but in systems
|
||||
* where message malleability or uniqueness of signatures is important this can
|
||||
* cause issues. This forgery can be blocked by all verifiers forcing signers
|
||||
* to use a normalized form.
|
||||
*
|
||||
* The lower-S form reduces the size of signatures slightly on average when
|
||||
* variable length encodings (such as DER) are used and is cheap to verify,
|
||||
* making it a good choice. Security of always using lower-S is assured because
|
||||
* anyone can trivially modify a signature after the fact to enforce this
|
||||
* property anyway.
|
||||
*
|
||||
* The lower S value is always between 0x1 and
|
||||
* 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
|
||||
* inclusive.
|
||||
*
|
||||
* No other forms of ECDSA malleability are known and none seem likely, but
|
||||
* there is no formal proof that ECDSA, even with this additional restriction,
|
||||
* is free of other malleability. Commonly used serialization schemes will also
|
||||
* accept various non-unique encodings, so care should be taken when this
|
||||
* property is required for an application.
|
||||
*
|
||||
* The secp256k1_ecdsa_sign function will by default create signatures in the
|
||||
* lower-S form, and secp256k1_ecdsa_verify will not accept others. In case
|
||||
* signatures come from a system that cannot enforce this property,
|
||||
* secp256k1_ecdsa_signature_normalize must be called before verification.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_signature_normalize(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature *sigout,
|
||||
const secp256k1_ecdsa_signature *sigin
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function.
|
||||
* If a data pointer is passed, it is assumed to be a pointer to 32 bytes of
|
||||
* extra entropy.
|
||||
*/
|
||||
extern const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979;
|
||||
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979;
|
||||
|
||||
/** A default safe nonce generation function (currently equal to secp256k1_nonce_function_rfc6979). */
|
||||
extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
|
||||
|
||||
SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_default;
|
||||
|
||||
/** Create an ECDSA signature.
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, the private key was invalid, or there is not
|
||||
* enough space in the signature (as indicated by siglen).
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
|
||||
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
|
||||
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
|
||||
* In/Out: siglen: pointer to an int with the length of sig, which will be updated
|
||||
* to contain the actual signature length (<=72).
|
||||
*
|
||||
* The sig always has an s value in the lower half of the range (From 0x1
|
||||
* to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
|
||||
* inclusive), unlike many other implementations.
|
||||
* With ECDSA a third-party can can forge a second distinct signature
|
||||
* of the same message given a single initial signature without knowing
|
||||
* the key by setting s to its additive inverse mod-order, 'flipping' the
|
||||
* sign of the random point R which is not included in the signature.
|
||||
* Since the forgery is of the same message this isn't universally
|
||||
* problematic, but in systems where message malleability or uniqueness
|
||||
* of signatures is important this can cause issues. This forgery can be
|
||||
* blocked by all verifiers forcing signers to use a canonical form. The
|
||||
* lower-S form reduces the size of signatures slightly on average when
|
||||
* variable length encodings (such as DER) are used and is cheap to
|
||||
* verify, making it a good choice. Security of always using lower-S is
|
||||
* assured because anyone can trivially modify a signature after the
|
||||
* fact to enforce this property. Adjusting it inside the signing
|
||||
* function avoids the need to re-serialize or have curve specific
|
||||
* constants outside of the library. By always using a canonical form
|
||||
* even in applications where it isn't needed it becomes possible to
|
||||
* impose a requirement later if a need is discovered.
|
||||
* No other forms of ECDSA malleability are known and none seem likely,
|
||||
* but there is no formal proof that ECDSA, even with this additional
|
||||
* restriction, is free of other malleability. Commonly used serialization
|
||||
* schemes will also accept various non-unique encodings, so care should
|
||||
* be taken when this property is required for an application.
|
||||
*/
|
||||
int secp256k1_ecdsa_sign(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
unsigned char *sig,
|
||||
int *siglen,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function_t noncefp,
|
||||
const void *ndata
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Create a compact ECDSA signature (64 byte + recovery id).
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, or the secret key was invalid.
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* 0: the nonce generation function failed, or the private key was invalid.
|
||||
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
|
||||
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
|
||||
* Out: sig: pointer to a 64-byte array where the signature will be placed (cannot be NULL)
|
||||
* In case 0 is returned, the returned signature length will be zero.
|
||||
* recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
|
||||
*
|
||||
* The created signature is always in lower-S form. See
|
||||
* secp256k1_ecdsa_signature_normalize for more details.
|
||||
*/
|
||||
int secp256k1_ecdsa_sign_compact(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function_t noncefp,
|
||||
const void *ndata,
|
||||
int *recid
|
||||
SECP256K1_API int secp256k1_ecdsa_sign(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature *sig,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function noncefp,
|
||||
const void *ndata
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Recover an ECDSA public key from a compact signature.
|
||||
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
|
||||
* 0: otherwise.
|
||||
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
|
||||
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
|
||||
* sig64: signature as 64 byte array (cannot be NULL)
|
||||
* compressed: whether to recover a compressed or uncompressed pubkey
|
||||
* recid: the recovery id (0-3, as returned by ecdsa_sign_compact)
|
||||
* Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL)
|
||||
* pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *sig64,
|
||||
unsigned char *pubkey,
|
||||
int *pubkeylen,
|
||||
int compressed,
|
||||
int recid
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Verify an ECDSA secret key.
|
||||
*
|
||||
* Returns: 1: secret key is valid
|
||||
* 0: secret key is invalid
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* Args: ctx: pointer to a context object (cannot be NULL)
|
||||
* In: seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *seckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Just validate a public key.
|
||||
* Returns: 1: public key is valid
|
||||
* 0: public key is invalid
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL).
|
||||
* pubkeylen: length of pubkey
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *pubkey,
|
||||
int pubkeylen
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
|
||||
const secp256k1_context* ctx,
|
||||
const unsigned char *seckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Compute the public key for a secret key.
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* compressed: whether the computed public key should be compressed
|
||||
* seckey: pointer to a 32-byte private key (cannot be NULL)
|
||||
* Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed)
|
||||
* area to store the public key (cannot be NULL)
|
||||
* pubkeylen: pointer to int that will be updated to contains the pubkey's
|
||||
* length (cannot be NULL)
|
||||
*
|
||||
* Returns: 1: secret was valid, public key stores
|
||||
* 0: secret was invalid, try again
|
||||
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* Out: pubkey: pointer to the created public key (cannot be NULL)
|
||||
* In: seckey: pointer to a 32-byte private key (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int *pubkeylen,
|
||||
const unsigned char *seckey,
|
||||
int compressed
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Decompress a public key.
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* In/Out: pubkey: pointer to a 65-byte array to put the decompressed public key.
|
||||
* It must contain a 33-byte or 65-byte public key already (cannot be NULL)
|
||||
* pubkeylen: pointer to the size of the public key pointed to by pubkey (cannot be NULL)
|
||||
* It will be updated to reflect the new size.
|
||||
* Returns: 0: pubkey was invalid
|
||||
* 1: pubkey was valid, and was replaced with its decompressed version
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int *pubkeylen
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *seckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Export a private key in DER format.
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
/** Tweak a private key by adding tweak to it.
|
||||
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
|
||||
* uniformly random 32-byte arrays, or if the resulting private key
|
||||
* would be invalid (only when the tweak is the complement of the
|
||||
* private key). 1 otherwise.
|
||||
* Args: ctx: pointer to a context object (cannot be NULL).
|
||||
* In/Out: seckey: pointer to a 32-byte private key.
|
||||
* In: tweak: pointer to a 32-byte tweak.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *seckey,
|
||||
unsigned char *privkey,
|
||||
int *privkeylen,
|
||||
int compressed
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Import a private key in DER format. */
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *privkey,
|
||||
int privkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a private key by adding tweak to it. */
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a public key by adding tweak times the generator to it.
|
||||
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
|
||||
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
|
||||
* uniformly random 32-byte arrays, or if the resulting public key
|
||||
* would be invalid (only when the tweak is the complement of the
|
||||
* corresponding private key). 1 otherwise.
|
||||
* Args: ctx: pointer to a context object initialized for validation
|
||||
* (cannot be NULL).
|
||||
* In/Out: pubkey: pointer to a public key object.
|
||||
* In: tweak: pointer to a 32-byte tweak.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int pubkeylen,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Tweak a private key by multiplying it with tweak. */
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a public key by multiplying it with tweak.
|
||||
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
|
||||
/** Tweak a private key by multiplying it by a tweak.
|
||||
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
|
||||
* uniformly random 32-byte arrays, or equal to zero. 1 otherwise.
|
||||
* Args: ctx: pointer to a context object (cannot be NULL).
|
||||
* In/Out: seckey: pointer to a 32-byte private key.
|
||||
* In: tweak: pointer to a 32-byte tweak.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int pubkeylen,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a public key by multiplying it by a tweak value.
|
||||
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
|
||||
* uniformly random 32-byte arrays, or equal to zero. 1 otherwise.
|
||||
* Args: ctx: pointer to a context object initialized for validation
|
||||
* (cannot be NULL).
|
||||
* In/Out: pubkey: pointer to a public key obkect.
|
||||
* In: tweak: pointer to a 32-byte tweak.
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Updates the context randomization.
|
||||
* Returns: 1: randomization successfully updated
|
||||
* 0: error
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* seed32: pointer to a 32-byte random seed (NULL resets to initial state)
|
||||
* Args: ctx: pointer to a context object (cannot be NULL)
|
||||
* In: seed32: pointer to a 32-byte random seed (NULL resets to initial state)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
|
||||
secp256k1_context_t* ctx,
|
||||
const unsigned char *seed32
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
|
||||
secp256k1_context* ctx,
|
||||
const unsigned char *seed32
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** Add a number of public keys together.
|
||||
* Returns: 1: the sum of the public keys is valid.
|
||||
* 0: the sum of the public keys is not valid.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: out: pointer to a public key object for placing the resulting public key
|
||||
* (cannot be NULL)
|
||||
* In: ins: pointer to array of pointers to public keys (cannot be NULL)
|
||||
* n: the number of public keys to add together (must be at least 1)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey *out,
|
||||
const secp256k1_pubkey * const * ins,
|
||||
size_t n
|
||||
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
||||
31
include/secp256k1_ecdh.h
Normal file
31
include/secp256k1_ecdh.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _SECP256K1_ECDH_
|
||||
# define _SECP256K1_ECDH_
|
||||
|
||||
# include "secp256k1.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
/** Compute an EC Diffie-Hellman secret in constant time
|
||||
* Returns: 1: exponentiation was successful
|
||||
* 0: scalar was invalid (zero or overflow)
|
||||
* Args: ctx: pointer to a context object (cannot be NULL)
|
||||
* Out: result: a 32-byte array which will be populated by an ECDH
|
||||
* secret computed from the point and scalar
|
||||
* In: pubkey: a pointer to a secp256k1_pubkey containing an
|
||||
* initialized public key
|
||||
* privkey: a 32-byte scalar with which to multiply the point
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *result,
|
||||
const secp256k1_pubkey *pubkey,
|
||||
const unsigned char *privkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
110
include/secp256k1_recovery.h
Normal file
110
include/secp256k1_recovery.h
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef _SECP256K1_RECOVERY_
|
||||
# define _SECP256K1_RECOVERY_
|
||||
|
||||
# include "secp256k1.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
/** Opaque data structured that holds a parsed ECDSA signature,
|
||||
* supporting pubkey recovery.
|
||||
*
|
||||
* The exact representation of data inside is implementation defined and not
|
||||
* guaranteed to be portable between different platforms or versions. It is
|
||||
* however guaranteed to be 65 bytes in size, and can be safely copied/moved.
|
||||
* If you need to convert to a format suitable for storage or transmission, use
|
||||
* the secp256k1_ecdsa_signature_serialize_* and
|
||||
* secp256k1_ecdsa_signature_parse_* functions.
|
||||
*
|
||||
* Furthermore, it is guaranteed that identical signatures (including their
|
||||
* recoverability) will have identical representation, so they can be
|
||||
* memcmp'ed.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned char data[65];
|
||||
} secp256k1_ecdsa_recoverable_signature;
|
||||
|
||||
/** Parse a compact ECDSA signature (64 bytes + recovery id).
|
||||
*
|
||||
* Returns: 1 when the signature could be parsed, 0 otherwise
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: sig: a pointer to a signature object
|
||||
* In: input64: a pointer to a 64-byte compact signature
|
||||
* recid: the recovery id (0, 1, 2 or 3)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_recoverable_signature* sig,
|
||||
const unsigned char *input64,
|
||||
int recid
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Convert a recoverable signature into a normal signature.
|
||||
*
|
||||
* Returns: 1
|
||||
* Out: sig: a pointer to a normal signature (cannot be NULL).
|
||||
* In: sigin: a pointer to a recoverable signature (cannot be NULL).
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_signature* sig,
|
||||
const secp256k1_ecdsa_recoverable_signature* sigin
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
|
||||
*
|
||||
* Returns: 1
|
||||
* Args: ctx: a secp256k1 context object
|
||||
* Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
|
||||
* recid: a pointer to an integer to hold the recovery id (can be NULL).
|
||||
* In: sig: a pointer to an initialized signature object (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *output64,
|
||||
int *recid,
|
||||
const secp256k1_ecdsa_recoverable_signature* sig
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Create a recoverable ECDSA signature.
|
||||
*
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, or the private key was invalid.
|
||||
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used
|
||||
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function noncefp,
|
||||
const void *ndata
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Recover an ECDSA public key from a signature.
|
||||
*
|
||||
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
|
||||
* 0: otherwise.
|
||||
* Args: ctx: pointer to a context object, initialized for verification (cannot be NULL)
|
||||
* Out: pubkey: pointer to the recovered public key (cannot be NULL)
|
||||
* In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL)
|
||||
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const secp256k1_ecdsa_recoverable_signature *sig,
|
||||
const unsigned char *msg32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
173
include/secp256k1_schnorr.h
Normal file
173
include/secp256k1_schnorr.h
Normal file
@@ -0,0 +1,173 @@
|
||||
#ifndef _SECP256K1_SCHNORR_
|
||||
# define _SECP256K1_SCHNORR_
|
||||
|
||||
# include "secp256k1.h"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
/** Create a signature using a custom EC-Schnorr-SHA256 construction. It
|
||||
* produces non-malleable 64-byte signatures which support public key recovery
|
||||
* batch validation, and multiparty signing.
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, or the private key was
|
||||
* invalid.
|
||||
* Args: ctx: pointer to a context object, initialized for signing
|
||||
* (cannot be NULL)
|
||||
* Out: sig64: pointer to a 64-byte array where the signature will be
|
||||
* placed (cannot be NULL)
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* noncefp:pointer to a nonce generation function. If NULL,
|
||||
* secp256k1_nonce_function_default is used
|
||||
* ndata: pointer to arbitrary data used by the nonce generation
|
||||
* function (can be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorr_sign(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function noncefp,
|
||||
const void *ndata
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Verify a signature created by secp256k1_schnorr_sign.
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* Args: ctx: a secp256k1 context object, initialized for verification.
|
||||
* In: sig64: the 64-byte signature being verified (cannot be NULL)
|
||||
* msg32: the 32-byte message hash being verified (cannot be NULL)
|
||||
* pubkey: the public key to verify with (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify(
|
||||
const secp256k1_context* ctx,
|
||||
const unsigned char *sig64,
|
||||
const unsigned char *msg32,
|
||||
const secp256k1_pubkey *pubkey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Recover an EC public key from a Schnorr signature created using
|
||||
* secp256k1_schnorr_sign.
|
||||
* Returns: 1: public key successfully recovered (which guarantees a correct
|
||||
* signature).
|
||||
* 0: otherwise.
|
||||
* Args: ctx: pointer to a context object, initialized for
|
||||
* verification (cannot be NULL)
|
||||
* Out: pubkey: pointer to a pubkey to set to the recovered public key
|
||||
* (cannot be NULL).
|
||||
* In: sig64: signature as 64 byte array (cannot be NULL)
|
||||
* msg32: the 32-byte message hash assumed to be signed (cannot
|
||||
* be NULL)
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorr_recover(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey *pubkey,
|
||||
const unsigned char *sig64,
|
||||
const unsigned char *msg32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Generate a nonce pair deterministically for use with
|
||||
* secp256k1_schnorr_partial_sign.
|
||||
* Returns: 1: valid nonce pair was generated.
|
||||
* 0: otherwise (nonce generation function failed)
|
||||
* Args: ctx: pointer to a context object, initialized for signing
|
||||
* (cannot be NULL)
|
||||
* Out: pubnonce: public side of the nonce (cannot be NULL)
|
||||
* privnonce32: private side of the nonce (32 byte) (cannot be NULL)
|
||||
* In: msg32: the 32-byte message hash assumed to be signed (cannot
|
||||
* be NULL)
|
||||
* sec32: the 32-byte private key (cannot be NULL)
|
||||
* noncefp: pointer to a nonce generation function. If NULL,
|
||||
* secp256k1_nonce_function_default is used
|
||||
* noncedata: pointer to arbitrary data used by the nonce generation
|
||||
* function (can be NULL)
|
||||
*
|
||||
* Do not use the output as a private/public key pair for signing/validation.
|
||||
*/
|
||||
SECP256K1_API int secp256k1_schnorr_generate_nonce_pair(
|
||||
const secp256k1_context* ctx,
|
||||
secp256k1_pubkey *pubnonce,
|
||||
unsigned char *privnonce32,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *sec32,
|
||||
secp256k1_nonce_function noncefp,
|
||||
const void* noncedata
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Produce a partial Schnorr signature, which can be combined using
|
||||
* secp256k1_schnorr_partial_combine, to end up with a full signature that is
|
||||
* verifiable using secp256k1_schnorr_verify.
|
||||
* Returns: 1: signature created successfully.
|
||||
* 0: no valid signature exists with this combination of keys, nonces
|
||||
* and message (chance around 1 in 2^128)
|
||||
* -1: invalid private key, nonce, or public nonces.
|
||||
* Args: ctx: pointer to context object, initialized for signing (cannot
|
||||
* be NULL)
|
||||
* Out: sig64: pointer to 64-byte array to put partial signature in
|
||||
* In: msg32: pointer to 32-byte message to sign
|
||||
* sec32: pointer to 32-byte private key
|
||||
* pubnonce_others: pointer to pubkey containing the sum of the other's
|
||||
* nonces (see secp256k1_ec_pubkey_combine)
|
||||
* secnonce32: pointer to 32-byte array containing our nonce
|
||||
*
|
||||
* The intended procedure for creating a multiparty signature is:
|
||||
* - Each signer S[i] with private key x[i] and public key Q[i] runs
|
||||
* secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of
|
||||
* private/public nonces.
|
||||
* - All signers communicate their public nonces to each other (revealing your
|
||||
* private nonce can lead to discovery of your private key, so it should be
|
||||
* considered secret).
|
||||
* - All signers combine all the public nonces they received (excluding their
|
||||
* own) using secp256k1_ec_pubkey_combine to obtain an
|
||||
* Rall[i] = sum(R[0..i-1,i+1..n]).
|
||||
* - All signers produce a partial signature using
|
||||
* secp256k1_schnorr_partial_sign, passing in their own private key x[i],
|
||||
* their own private nonce k[i], and the sum of the others' public nonces
|
||||
* Rall[i].
|
||||
* - All signers communicate their partial signatures to each other.
|
||||
* - Someone combines all partial signatures using
|
||||
* secp256k1_schnorr_partial_combine, to obtain a full signature.
|
||||
* - The resulting signature is validatable using secp256k1_schnorr_verify, with
|
||||
* public key equal to the result of secp256k1_ec_pubkey_combine of the
|
||||
* signers' public keys (sum(Q[0..n])).
|
||||
*
|
||||
* Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine
|
||||
* function take their arguments in any order, and it is possible to
|
||||
* pre-combine several inputs already with one call, and add more inputs later
|
||||
* by calling the function again (they are commutative and associative).
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *sec32,
|
||||
const secp256k1_pubkey *pubnonce_others,
|
||||
const unsigned char *secnonce32
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
|
||||
|
||||
/** Combine multiple Schnorr partial signatures.
|
||||
* Returns: 1: the passed signatures were successfully combined.
|
||||
* 0: the resulting signature is not valid (chance of 1 in 2^256)
|
||||
* -1: some inputs were invalid, or the signatures were not created
|
||||
* using the same set of nonces
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: sig64: pointer to a 64-byte array to place the combined signature
|
||||
* (cannot be NULL)
|
||||
* In: sig64sin: pointer to an array of n pointers to 64-byte input
|
||||
* signatures
|
||||
* n: the number of signatures to combine (at least 1)
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_combine(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *sig64,
|
||||
const unsigned char * const * sig64sin,
|
||||
size_t n
|
||||
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user