mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-10 10:52:31 -05:00
Use a flags bitfield for compressed option to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export
This commit is contained in:
parent
05732c5a5f
commit
486b9bb8ce
9 changed files with 27 additions and 22 deletions
|
@ -137,6 +137,9 @@ typedef int (*secp256k1_nonce_function_t)(
|
||||||
# define SECP256K1_CONTEXT_VERIFY (1 << 0)
|
# define SECP256K1_CONTEXT_VERIFY (1 << 0)
|
||||||
# define SECP256K1_CONTEXT_SIGN (1 << 1)
|
# define SECP256K1_CONTEXT_SIGN (1 << 1)
|
||||||
|
|
||||||
|
/** Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export. */
|
||||||
|
# define SECP256K1_EC_COMPRESSED (1 << 0)
|
||||||
|
|
||||||
/** Create a secp256k1 context object.
|
/** Create a secp256k1 context object.
|
||||||
*
|
*
|
||||||
* Returns: a newly created context object.
|
* Returns: a newly created context object.
|
||||||
|
@ -243,14 +246,15 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
|
||||||
* size.
|
* size.
|
||||||
* In: pubkey: a pointer to a secp256k1_pubkey_t containing an initialized
|
* In: pubkey: a pointer to a secp256k1_pubkey_t containing an initialized
|
||||||
* public key.
|
* public key.
|
||||||
* compressed: whether to serialize in compressed format.
|
* flags: SECP256K1_EC_COMPRESSED if serialization should be in
|
||||||
|
* compressed format.
|
||||||
*/
|
*/
|
||||||
int secp256k1_ec_pubkey_serialize(
|
int secp256k1_ec_pubkey_serialize(
|
||||||
const secp256k1_context_t* ctx,
|
const secp256k1_context_t* ctx,
|
||||||
unsigned char *output,
|
unsigned char *output,
|
||||||
size_t *outputlen,
|
size_t *outputlen,
|
||||||
const secp256k1_pubkey_t* pubkey,
|
const secp256k1_pubkey_t* pubkey,
|
||||||
int compressed
|
unsigned int flags
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||||
|
|
||||||
/** Parse a DER ECDSA signature.
|
/** Parse a DER ECDSA signature.
|
||||||
|
@ -396,7 +400,8 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||||
* privkeylen: Pointer to an int where the length of the private key in
|
* privkeylen: Pointer to an int where the length of the private key in
|
||||||
* privkey will be stored.
|
* privkey will be stored.
|
||||||
* In: seckey: pointer to a 32-byte secret key to export.
|
* In: seckey: pointer to a 32-byte secret key to export.
|
||||||
* compressed: whether the key should be exported in compressed format.
|
* flags: SECP256K1_EC_COMPRESSED if the key should be exported in
|
||||||
|
* compressed format.
|
||||||
*
|
*
|
||||||
* This function is purely meant for compatibility with applications that
|
* This function is purely meant for compatibility with applications that
|
||||||
* require BER encoded keys. When working with secp256k1-specific code, the
|
* require BER encoded keys. When working with secp256k1-specific code, the
|
||||||
|
@ -410,7 +415,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export(
|
||||||
unsigned char *privkey,
|
unsigned char *privkey,
|
||||||
size_t *privkeylen,
|
size_t *privkeylen,
|
||||||
const unsigned char *seckey,
|
const unsigned char *seckey,
|
||||||
int compressed
|
unsigned int flags
|
||||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||||
|
|
||||||
/** Import a private key in DER format.
|
/** Import a private key in DER format.
|
||||||
|
|
|
@ -27,7 +27,7 @@ void bench_recover(void* arg) {
|
||||||
secp256k1_ecdsa_recoverable_signature_t sig;
|
secp256k1_ecdsa_recoverable_signature_t sig;
|
||||||
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2));
|
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2));
|
||||||
CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg));
|
CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg));
|
||||||
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, 1));
|
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED));
|
||||||
for (j = 0; j < 32; j++) {
|
for (j = 0; j < 32; j++) {
|
||||||
data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
|
data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
|
||||||
data->msg[j] = data->sig[j]; /* Move former R to message. */
|
data->msg[j] = data->sig[j]; /* Move former R to message. */
|
||||||
|
|
|
@ -37,7 +37,7 @@ static void benchmark_schnorr_init(void* arg) {
|
||||||
secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL);
|
secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL);
|
||||||
data->sigs[k].pubkeylen = 33;
|
data->sigs[k].pubkeylen = 33;
|
||||||
CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key));
|
CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key));
|
||||||
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, 1));
|
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ int main(void) {
|
||||||
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
|
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
|
||||||
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
|
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
|
||||||
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
|
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
|
||||||
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, 1) == 1);
|
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
|
||||||
|
|
||||||
run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
|
run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
#include "ecmult_gen.h"
|
#include "ecmult_gen.h"
|
||||||
|
|
||||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, size_t size);
|
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, size_t size);
|
||||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, size_t *size, int compressed);
|
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, size_t *size, unsigned int flags);
|
||||||
|
|
||||||
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, size_t privkeylen);
|
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, size_t privkeylen);
|
||||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar_t *key, int compressed);
|
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar_t *key, unsigned int flags);
|
||||||
|
|
||||||
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
|
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
|
||||||
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||||
|
|
|
@ -33,14 +33,14 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, size_t *size, int compressed) {
|
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, size_t *size, unsigned int flags) {
|
||||||
if (secp256k1_ge_is_infinity(elem)) {
|
if (secp256k1_ge_is_infinity(elem)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
secp256k1_fe_normalize_var(&elem->x);
|
secp256k1_fe_normalize_var(&elem->x);
|
||||||
secp256k1_fe_normalize_var(&elem->y);
|
secp256k1_fe_normalize_var(&elem->y);
|
||||||
secp256k1_fe_get_b32(&pub[1], &elem->x);
|
secp256k1_fe_get_b32(&pub[1], &elem->x);
|
||||||
if (compressed) {
|
if (flags & SECP256K1_EC_COMPRESSED) {
|
||||||
*size = 33;
|
*size = 33;
|
||||||
pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00);
|
pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00);
|
||||||
} else {
|
} else {
|
||||||
|
@ -94,13 +94,13 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned
|
||||||
return !overflow;
|
return !overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar_t *key, int compressed) {
|
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, size_t *privkeylen, const secp256k1_scalar_t *key, unsigned int flags) {
|
||||||
secp256k1_gej_t rp;
|
secp256k1_gej_t rp;
|
||||||
secp256k1_ge_t r;
|
secp256k1_ge_t r;
|
||||||
size_t pubkeylen = 0;
|
size_t pubkeylen = 0;
|
||||||
secp256k1_ecmult_gen(ctx, &rp, key);
|
secp256k1_ecmult_gen(ctx, &rp, key);
|
||||||
secp256k1_ge_set_gej(&r, &rp);
|
secp256k1_ge_set_gej(&r, &rp);
|
||||||
if (compressed) {
|
if (flags & SECP256K1_EC_COMPRESSED) {
|
||||||
static const unsigned char begin[] = {
|
static const unsigned char begin[] = {
|
||||||
0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
|
0x30,0x81,0xD3,0x02,0x01,0x01,0x04,0x20
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,7 @@ void test_ecdh_generator_basepoint(void) {
|
||||||
CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1);
|
CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1);
|
||||||
/* compute "explicitly" */
|
/* compute "explicitly" */
|
||||||
CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1);
|
CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1);
|
||||||
CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], 1) == 1);
|
CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1);
|
||||||
CHECK(point_ser_len == sizeof(point_ser));
|
CHECK(point_ser_len == sizeof(point_ser));
|
||||||
secp256k1_sha256_initialize(&sha);
|
secp256k1_sha256_initialize(&sha);
|
||||||
secp256k1_sha256_write(&sha, point_ser, point_ser_len);
|
secp256k1_sha256_write(&sha, point_ser, point_ser_len);
|
||||||
|
|
|
@ -154,12 +154,12 @@ int secp256k1_ec_pubkey_parse(const secp256k1_context_t* ctx, secp256k1_pubkey_t
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int secp256k1_ec_pubkey_serialize(const secp256k1_context_t* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey_t* pubkey, int compressed) {
|
int secp256k1_ec_pubkey_serialize(const secp256k1_context_t* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey_t* pubkey, unsigned int flags) {
|
||||||
secp256k1_ge_t Q;
|
secp256k1_ge_t Q;
|
||||||
|
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
return (secp256k1_pubkey_load(ctx, &Q, pubkey) &&
|
return (secp256k1_pubkey_load(ctx, &Q, pubkey) &&
|
||||||
secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, compressed));
|
secp256k1_eckey_pubkey_serialize(&Q, output, outputlen, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void secp256k1_ecdsa_signature_load(const secp256k1_context_t* ctx, secp256k1_scalar_t* r, secp256k1_scalar_t* s, const secp256k1_ecdsa_signature_t* sig) {
|
static void secp256k1_ecdsa_signature_load(const secp256k1_context_t* ctx, secp256k1_scalar_t* r, secp256k1_scalar_t* s, const secp256k1_ecdsa_signature_t* sig) {
|
||||||
|
@ -438,7 +438,7 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, secp256k1_pubk
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *seckey, int compressed) {
|
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *seckey, unsigned int flags) {
|
||||||
secp256k1_scalar_t key;
|
secp256k1_scalar_t key;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
VERIFY_CHECK(ctx != NULL);
|
VERIFY_CHECK(ctx != NULL);
|
||||||
|
@ -448,7 +448,7 @@ int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, unsigned char *p
|
||||||
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
||||||
|
|
||||||
secp256k1_scalar_set_b32(&key, seckey, NULL);
|
secp256k1_scalar_set_b32(&key, seckey, NULL);
|
||||||
ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed);
|
ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, flags);
|
||||||
secp256k1_scalar_clear(&key);
|
secp256k1_scalar_clear(&key);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1871,7 +1871,7 @@ void test_ecdsa_end_to_end(void) {
|
||||||
CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1);
|
CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1);
|
||||||
|
|
||||||
/* Verify private key import and export. */
|
/* Verify private key import and export. */
|
||||||
CHECK(secp256k1_ec_privkey_export(ctx, seckey, &seckeylen, privkey, secp256k1_rand32() % 2) == 1);
|
CHECK(secp256k1_ec_privkey_export(ctx, seckey, &seckeylen, privkey, (secp256k1_rand32() % 2) == 1) ? SECP256K1_EC_COMPRESSED : 0);
|
||||||
CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1);
|
CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1);
|
||||||
CHECK(memcmp(privkey, privkey2, 32) == 0);
|
CHECK(memcmp(privkey, privkey2, 32) == 0);
|
||||||
|
|
||||||
|
@ -1979,7 +1979,7 @@ void test_random_pubkeys(void) {
|
||||||
size_t size = len;
|
size_t size = len;
|
||||||
firstb = in[0];
|
firstb = in[0];
|
||||||
/* If the pubkey can be parsed, it should round-trip... */
|
/* If the pubkey can be parsed, it should round-trip... */
|
||||||
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, len == 33));
|
CHECK(secp256k1_eckey_pubkey_serialize(&elem, out, &size, (len == 33) ? SECP256K1_EC_COMPRESSED : 0));
|
||||||
CHECK(size == len);
|
CHECK(size == len);
|
||||||
CHECK(memcmp(&in[1], &out[1], len-1) == 0);
|
CHECK(memcmp(&in[1], &out[1], len-1) == 0);
|
||||||
/* ... except for the type of hybrid inputs. */
|
/* ... except for the type of hybrid inputs. */
|
||||||
|
@ -2156,7 +2156,7 @@ void test_ecdsa_edge_cases(void) {
|
||||||
size_t outlen = 300;
|
size_t outlen = 300;
|
||||||
CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, 0));
|
CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, 0));
|
||||||
outlen = 300;
|
outlen = 300;
|
||||||
CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, 1));
|
CHECK(!secp256k1_ec_privkey_export(ctx, privkey, &outlen, seckey, SECP256K1_EC_COMPRESSED));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2171,7 +2171,7 @@ EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) {
|
||||||
const unsigned char* pbegin = privkey;
|
const unsigned char* pbegin = privkey;
|
||||||
int compr = secp256k1_rand32() & 1;
|
int compr = secp256k1_rand32() & 1;
|
||||||
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
|
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));
|
CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr ? SECP256K1_EC_COMPRESSED : 0));
|
||||||
CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
|
CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
|
||||||
CHECK(EC_KEY_check_key(ec_key));
|
CHECK(EC_KEY_check_key(ec_key));
|
||||||
return ec_key;
|
return ec_key;
|
||||||
|
|
Loading…
Add table
Reference in a new issue