Overhaul flags handling
This commit is contained in:
parent
1a368980c8
commit
9234391ed4
|
@ -34,22 +34,22 @@
|
|||
* privkeylen: Pointer to an int where the length of the private key in
|
||||
* privkey will be stored.
|
||||
* In: seckey: pointer to a 32-byte secret key to export.
|
||||
* flags: SECP256K1_EC_COMPRESSED if the key should be exported in
|
||||
* compressed format.
|
||||
* compressed: 1 if the key should be exported in
|
||||
* compressed format, 0 otherwise
|
||||
*
|
||||
* This function is purely meant for compatibility with applications that
|
||||
* require BER encoded keys. When working with secp256k1-specific code, the
|
||||
* simple 32-byte private keys are sufficient.
|
||||
*
|
||||
* Note that this function does not guarantee correct DER output. It is
|
||||
* guaranteed to be parsable by secp256k1_ec_privkey_import.
|
||||
* guaranteed to be parsable by secp256k1_ec_privkey_import_der
|
||||
*/
|
||||
static SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export_der(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *privkey,
|
||||
size_t *privkeylen,
|
||||
const unsigned char *seckey,
|
||||
unsigned int flags
|
||||
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.
|
||||
|
@ -116,13 +116,13 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar *key, const unsigned c
|
|||
return !overflow;
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar *key, unsigned int flags) {
|
||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar *key, int compressed) {
|
||||
secp256k1_gej rp;
|
||||
secp256k1_ge r;
|
||||
size_t pubkeylen = 0;
|
||||
secp256k1_ecmult_gen(ctx, &rp, key);
|
||||
secp256k1_ge_set_gej(&r, &rp);
|
||||
if (flags & SECP256K1_EC_COMPRESSED) {
|
||||
if (compressed) {
|
||||
static const unsigned char begin[] = {
|
||||
0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
|
||||
};
|
||||
|
@ -176,7 +176,7 @@ static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_ec_privkey_export_der(const secp256k1_context* ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *seckey, unsigned int flags) {
|
||||
static int secp256k1_ec_privkey_export_der(const secp256k1_context* ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *seckey, int compressed) {
|
||||
secp256k1_scalar key;
|
||||
int ret = 0;
|
||||
VERIFY_CHECK(ctx != NULL);
|
||||
|
@ -186,7 +186,7 @@ static int secp256k1_ec_privkey_export_der(const secp256k1_context* ctx, unsigne
|
|||
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
||||
|
||||
secp256k1_scalar_set_b32(&key, seckey, NULL);
|
||||
ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, flags);
|
||||
ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed);
|
||||
secp256k1_scalar_clear(&key);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -147,22 +147,24 @@ typedef int (*secp256k1_nonce_function)(
|
|||
# define SECP256K1_ARG_NONNULL(_x)
|
||||
# endif
|
||||
|
||||
/** 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 (SECP256K1_CONTEXT_VERIFY_BIT|SECP256K1_CONTEXT_CHECK_BIT)
|
||||
# define SECP256K1_CONTEXT_SIGN (SECP256K1_CONTEXT_SIGN_BIT|SECP256K1_CONTEXT_CHECK_BIT)
|
||||
# define SECP256K1_CONTEXT_NONE (SECP256K1_CONTEXT_CHECK_BIT)
|
||||
#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)
|
||||
|
||||
# define SECP256K1_CONTEXT_VERIFY_BIT (1 << 2)
|
||||
# define SECP256K1_CONTEXT_SIGN_BIT (2 << 2)
|
||||
# define SECP256K1_CONTEXT_CHECK_BIT (1)
|
||||
|
||||
/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */
|
||||
# define SECP256K1_EC_COMPRESSED (SECP256K1_EC_COMPRESSED_BIT|SECP256K1_EC_CHECK_BIT)
|
||||
# define SECP256K1_EC_UNCOMPRESSED (SECP256K1_EC_CHECK_BIT)
|
||||
#define SECP256K1_EC_COMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION | SECP256K1_FLAGS_BIT_COMPRESSION)
|
||||
#define SECP256K1_EC_UNCOMPRESSED (SECP256K1_FLAGS_TYPE_COMPRESSION)
|
||||
|
||||
# define SECP256K1_EC_COMPRESSED_BIT (1 << 2)
|
||||
# define SECP256K1_EC_CHECK_BIT (2)
|
||||
|
||||
/** Create a secp256k1 context object.
|
||||
*
|
||||
* Returns: a newly created context object.
|
||||
|
|
|
@ -15,10 +15,7 @@
|
|||
#include "ecmult_gen.h"
|
||||
|
||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size);
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, unsigned int flags);
|
||||
|
||||
static int secp256k1_eckey_privkey_parse(secp256k1_scalar *key, const unsigned char *privkey, size_t privkeylen);
|
||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar *key, unsigned int flags);
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed);
|
||||
|
||||
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak);
|
||||
|
|
|
@ -33,14 +33,14 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char
|
|||
}
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, unsigned int flags) {
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) {
|
||||
if (secp256k1_ge_is_infinity(elem)) {
|
||||
return 0;
|
||||
}
|
||||
secp256k1_fe_normalize_var(&elem->x);
|
||||
secp256k1_fe_normalize_var(&elem->y);
|
||||
secp256k1_fe_get_b32(&pub[1], &elem->x);
|
||||
if (flags & SECP256K1_EC_COMPRESSED_BIT) {
|
||||
if (compressed) {
|
||||
*size = 33;
|
||||
pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00);
|
||||
} else {
|
||||
|
|
|
@ -62,7 +62,7 @@ secp256k1_context* secp256k1_context_create(unsigned int flags) {
|
|||
ret->illegal_callback = default_illegal_callback;
|
||||
ret->error_callback = default_error_callback;
|
||||
|
||||
if (EXPECT(!(flags & SECP256K1_CONTEXT_CHECK_BIT), 0)) {
|
||||
if (EXPECT((flags & SECP256K1_FLAGS_TYPE_MASK) != SECP256K1_FLAGS_TYPE_CONTEXT, 0)) {
|
||||
secp256k1_callback_call(&ret->illegal_callback,
|
||||
"Invalid flags");
|
||||
free(ret);
|
||||
|
@ -72,10 +72,10 @@ secp256k1_context* secp256k1_context_create(unsigned int flags) {
|
|||
secp256k1_ecmult_context_init(&ret->ecmult_ctx);
|
||||
secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx);
|
||||
|
||||
if (flags & SECP256K1_CONTEXT_SIGN_BIT) {
|
||||
if (flags & SECP256K1_FLAGS_BIT_CONTEXT_SIGN) {
|
||||
secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx, &ret->error_callback);
|
||||
}
|
||||
if (flags & SECP256K1_CONTEXT_VERIFY_BIT) {
|
||||
if (flags & SECP256K1_FLAGS_BIT_CONTEXT_VERIFY) {
|
||||
secp256k1_ecmult_context_build(&ret->ecmult_ctx, &ret->error_callback);
|
||||
}
|
||||
|
||||
|
@ -173,9 +173,9 @@ int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *o
|
|||
ARG_CHECK(output != NULL);
|
||||
ARG_CHECK(outputlen != NULL);
|
||||
ARG_CHECK(pubkey != NULL);
|
||||
ARG_CHECK(flags & SECP256K1_EC_CHECK_BIT);
|
||||
ARG_CHECK((flags & SECP256K1_FLAGS_TYPE_MASK) == SECP256K1_FLAGS_TYPE_COMPRESSION);
|
||||
return (secp256k1_pubkey_load(ctx, &Q, pubkey) &&
|
||||
secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, flags));
|
||||
secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, flags & SECP256K1_FLAGS_BIT_COMPRESSION));
|
||||
}
|
||||
|
||||
static void secp256k1_ecdsa_signature_load(const secp256k1_context* ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_ecdsa_signature* sig) {
|
||||
|
|
18
src/tests.c
18
src/tests.c
|
@ -1544,9 +1544,9 @@ void test_point_times_order(const secp256k1_gej *point) {
|
|||
secp256k1_ge_set_gej(&res3, &res1);
|
||||
CHECK(secp256k1_ge_is_infinity(&res3));
|
||||
CHECK(secp256k1_ge_is_valid_var(&res3) == 0);
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, SECP256K1_EC_UNCOMPRESSED) == 0);
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 0) == 0);
|
||||
psize = 65;
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, SECP256K1_EC_COMPRESSED) == 0);
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&res3, pub, &psize, 1) == 0);
|
||||
/* check zero/one edge cases */
|
||||
secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &zero, &zero);
|
||||
secp256k1_ge_set_gej(&res3, &res1);
|
||||
|
@ -2580,7 +2580,7 @@ void test_ecdsa_end_to_end(void) {
|
|||
CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1);
|
||||
|
||||
/* Verify private key import and export. */
|
||||
CHECK(secp256k1_ec_privkey_export_der(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1 ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED));
|
||||
CHECK(secp256k1_ec_privkey_export_der(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1));
|
||||
CHECK(secp256k1_ec_privkey_import_der(ctx, privkey2, seckey, seckeylen) == 1);
|
||||
CHECK(memcmp(privkey, privkey2, 32) == 0);
|
||||
|
||||
|
@ -2698,7 +2698,7 @@ void test_random_pubkeys(void) {
|
|||
size_t size = len;
|
||||
firstb = in[0];
|
||||
/* If the pubkey can be parsed, it should round-trip... */
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, (len == 33) ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED));
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33));
|
||||
CHECK(size == len);
|
||||
CHECK(memcmp(&in[1], &out[1], len-1) == 0);
|
||||
/* ... except for the type of hybrid inputs. */
|
||||
|
@ -2706,7 +2706,7 @@ void test_random_pubkeys(void) {
|
|||
CHECK(in[0] == out[0]);
|
||||
}
|
||||
size = 65;
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, SECP256K1_EC_UNCOMPRESSED));
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, in, &size, 0));
|
||||
CHECK(size == 65);
|
||||
CHECK(secp256k1_eckey_pubkey_parse(&elem2, in, size));
|
||||
ge_equals_ge(&elem,&elem2);
|
||||
|
@ -2722,7 +2722,7 @@ void test_random_pubkeys(void) {
|
|||
}
|
||||
if (res) {
|
||||
ge_equals_ge(&elem,&elem2);
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, SECP256K1_EC_UNCOMPRESSED));
|
||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, 0));
|
||||
CHECK(memcmp(&in[1], &out[1], 64) == 0);
|
||||
}
|
||||
}
|
||||
|
@ -3399,9 +3399,9 @@ void test_ecdsa_edge_cases(void) {
|
|||
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
|
||||
};
|
||||
size_t outlen = 300;
|
||||
CHECK(!secp256k1_ec_privkey_export_der(ctx, privkey, &outlen, seckey, SECP256K1_EC_UNCOMPRESSED));
|
||||
CHECK(!secp256k1_ec_privkey_export_der(ctx, privkey, &outlen, seckey, 0));
|
||||
outlen = 300;
|
||||
CHECK(!secp256k1_ec_privkey_export_der(ctx, privkey, &outlen, seckey, SECP256K1_EC_COMPRESSED));
|
||||
CHECK(!secp256k1_ec_privkey_export_der(ctx, privkey, &outlen, seckey, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3416,7 +3416,7 @@ EC_KEY *get_openssl_key(const secp256k1_scalar *key) {
|
|||
const unsigned char* pbegin = privkey;
|
||||
int compr = secp256k1_rand_bits(1);
|
||||
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED));
|
||||
CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr));
|
||||
CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
|
||||
CHECK(EC_KEY_check_key(ec_key));
|
||||
return ec_key;
|
||||
|
|
Loading…
Reference in New Issue