Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split secp256k1_ec_pubkey_decompress into in-place and copy variants #250

Merged
merged 1 commit into from
Jun 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions include/secp256k1.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,18 +262,20 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(

/** Decompress a public key.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just replace the old function.

* 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
* In: pubkeyin: pointer to a 33-byte or 65-byte public key (cannot be NULL)
* In/Out: pubkeyout: pointer to a 65-byte array to put the decompressed public key (cannot be NULL)
* May alias pubkeyin.
* pubkeylen: pointer to the size of the public key pointed to by pubkeyin (cannot be NULL)
* It will be updated to reflect the size of the public key in pubkeyout.
* Returns: 0: pubkeyin was invalid
* 1: pubkeyin was valid, and pubkeyout is its decompressed version
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress(
const secp256k1_context_t* ctx,
unsigned char *pubkey,
const unsigned char *pubkeyin,
unsigned char *pubkeyout,
int *pubkeylen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

/** Export a private key in DER format.
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
Expand Down
9 changes: 5 additions & 4 deletions src/secp256k1.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,16 @@ int secp256k1_ec_pubkey_create(const secp256k1_context_t* ctx, unsigned char *pu
return ret;
}

int secp256k1_ec_pubkey_decompress(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen) {
int secp256k1_ec_pubkey_decompress(const secp256k1_context_t* ctx, const unsigned char *pubkeyin, unsigned char *pubkeyout, int *pubkeylen) {
secp256k1_ge_t p;
int ret = 0;
DEBUG_CHECK(pubkey != NULL);
DEBUG_CHECK(pubkeyin != NULL);
DEBUG_CHECK(pubkeyout != NULL);
DEBUG_CHECK(pubkeylen != NULL);
(void)ctx;

if (secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) {
ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0);
if (secp256k1_eckey_pubkey_parse(&p, pubkeyin, *pubkeylen)) {
ret = secp256k1_eckey_pubkey_serialize(&p, pubkeyout, pubkeylen, 0);
}
return ret;
}
Expand Down
14 changes: 13 additions & 1 deletion src/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -1511,7 +1511,19 @@ void test_ecdsa_end_to_end(void) {
CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);
CHECK(secp256k1_ec_pubkey_create(ctx, pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1);
if (secp256k1_rand32() & 1) {
CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, &pubkeylen));
unsigned char pubkey2[65] = {0};
int pubkey2len = pubkeylen;
/* Decompress into a new array */
CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, pubkey2, &pubkey2len));
/* Check that the key was changed iff it was originally compressed */
if (pubkeylen == 65) {
CHECK(memcmp(pubkey, pubkey2, 65) == 0);
} else {
CHECK(memcmp(pubkey, pubkey2, 65) != 0);
}
/* Decompress in place */
CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, pubkey, &pubkeylen));
CHECK(memcmp(pubkey, pubkey2, 65) == 0);
}
CHECK(secp256k1_ec_pubkey_verify(ctx, pubkey, pubkeylen));

Expand Down