|
@ -66,6 +66,39 @@ struct secp256k1_context_struct { |
|
|
secp256k1_callback error_callback; |
|
|
secp256k1_callback error_callback; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { |
|
|
|
|
|
if (sizeof(secp256k1_ge_storage) == 64) { |
|
|
|
|
|
/* When the secp256k1_ge_storage type is exactly 64 byte, use its
|
|
|
|
|
|
* representation inside secp256k1_pubkey, as conversion is very fast. |
|
|
|
|
|
* Note that secp256k1_pubkey_save must use the same representation. */ |
|
|
|
|
|
secp256k1_ge_storage s; |
|
|
|
|
|
memcpy(&s, &pubkey->data[0], 64); |
|
|
|
|
|
secp256k1_ge_from_storage(ge, &s); |
|
|
|
|
|
} else { |
|
|
|
|
|
/* Otherwise, fall back to 32-byte big endian for X and Y. */ |
|
|
|
|
|
secp256k1_fe x, y; |
|
|
|
|
|
secp256k1_fe_set_b32(&x, pubkey->data); |
|
|
|
|
|
secp256k1_fe_set_b32(&y, pubkey->data + 32); |
|
|
|
|
|
secp256k1_ge_set_xy(ge, &x, &y); |
|
|
|
|
|
} |
|
|
|
|
|
ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { |
|
|
|
|
|
if (sizeof(secp256k1_ge_storage) == 64) { |
|
|
|
|
|
secp256k1_ge_storage s; |
|
|
|
|
|
secp256k1_ge_to_storage(&s, ge); |
|
|
|
|
|
memcpy(&pubkey->data[0], &s, 64); |
|
|
|
|
|
} else { |
|
|
|
|
|
VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); |
|
|
|
|
|
secp256k1_fe_normalize_var(&ge->x); |
|
|
|
|
|
secp256k1_fe_normalize_var(&ge->y); |
|
|
|
|
|
secp256k1_fe_get_b32(pubkey->data, &ge->x); |
|
|
|
|
|
secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#ifndef EXTERNAL_SECP256 |
|
|
#ifndef EXTERNAL_SECP256 |
|
|
|
|
|
|
|
|
secp256k1_context* secp256k1_context_create(unsigned int flags) { |
|
|
secp256k1_context* secp256k1_context_create(unsigned int flags) { |
|
@ -139,40 +172,6 @@ void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(co |
|
|
ctx->error_callback.data = data; |
|
|
ctx->error_callback.data = data; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) { |
|
|
|
|
|
if (sizeof(secp256k1_ge_storage) == 64) { |
|
|
|
|
|
/* When the secp256k1_ge_storage type is exactly 64 byte, use its
|
|
|
|
|
|
* representation inside secp256k1_pubkey, as conversion is very fast. |
|
|
|
|
|
* Note that secp256k1_pubkey_save must use the same representation. */ |
|
|
|
|
|
secp256k1_ge_storage s; |
|
|
|
|
|
memcpy(&s, &pubkey->data[0], 64); |
|
|
|
|
|
secp256k1_ge_from_storage(ge, &s); |
|
|
|
|
|
} else { |
|
|
|
|
|
/* Otherwise, fall back to 32-byte big endian for X and Y. */ |
|
|
|
|
|
secp256k1_fe x, y; |
|
|
|
|
|
secp256k1_fe_set_b32(&x, pubkey->data); |
|
|
|
|
|
secp256k1_fe_set_b32(&y, pubkey->data + 32); |
|
|
|
|
|
secp256k1_ge_set_xy(ge, &x, &y); |
|
|
|
|
|
} |
|
|
|
|
|
ARG_CHECK(!secp256k1_fe_is_zero(&ge->x)); |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) { |
|
|
|
|
|
if (sizeof(secp256k1_ge_storage) == 64) { |
|
|
|
|
|
secp256k1_ge_storage s; |
|
|
|
|
|
secp256k1_ge_to_storage(&s, ge); |
|
|
|
|
|
memcpy(&pubkey->data[0], &s, 64); |
|
|
|
|
|
} else { |
|
|
|
|
|
VERIFY_CHECK(!secp256k1_ge_is_infinity(ge)); |
|
|
|
|
|
secp256k1_fe_normalize_var(&ge->x); |
|
|
|
|
|
secp256k1_fe_normalize_var(&ge->y); |
|
|
|
|
|
secp256k1_fe_get_b32(pubkey->data, &ge->x); |
|
|
|
|
|
secp256k1_fe_get_b32(pubkey->data + 32, &ge->y); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { |
|
|
int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) { |
|
|
secp256k1_ge Q; |
|
|
secp256k1_ge Q; |
|
|
|
|
|
|
|
|