[libsecp] Add negation functionality

This commit is contained in:
instagibbs 2016-08-29 11:51:33 -04:00 committed by Gregory Sanders
parent 9f4ea3d03f
commit bedb684e47
3 changed files with 56 additions and 0 deletions

View file

@ -485,6 +485,29 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
const unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Negates a private key in place.
*
* Returns: 1 always
* Args: ctx: pointer to a context object
* In/Out: pubkey: pointer to the public key to be negated (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_negate(
const secp256k1_context* ctx,
unsigned char *seckey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** Negates a public key in place.
*
* Returns: 1 always
* Args: ctx: pointer to a context object
* In/Out: pubkey: pointer to the public key to be negated (cannot be NULL)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_negate(
const secp256k1_context* ctx,
secp256k1_pubkey *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
/** 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

View file

@ -445,6 +445,30 @@ int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *p
return ret;
}
int secp256k1_ec_privkey_negate(const secp256k1_context* ctx, unsigned char *seckey) {
secp256k1_scalar sec;
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(seckey != NULL);
secp256k1_scalar_set_b32(&sec, seckey, NULL);
secp256k1_scalar_negate(&sec, &sec);
secp256k1_scalar_get_b32(seckey, &sec);
return 1;
}
int secp256k1_ec_pubkey_negate(const secp256k1_context* ctx, secp256k1_pubkey *pubkey) {
int ret = 0;
secp256k1_ge p;
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(pubkey != NULL);
ret = secp256k1_pubkey_load(ctx, &p, pubkey);
secp256k1_ge_neg(&p, &p);
secp256k1_pubkey_save(pubkey, &p);
return ret;
}
int secp256k1_ec_privkey_tweak_add(const secp256k1_context* ctx, unsigned char *seckey, const unsigned char *tweak) {
secp256k1_scalar term;
secp256k1_scalar sec;

View file

@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
@ -3482,6 +3483,7 @@ void test_ecdsa_end_to_end(void) {
unsigned char pubkeyc[65];
size_t pubkeyclen = 65;
secp256k1_pubkey pubkey;
secp256k1_pubkey pubkey_tmp;
unsigned char seckey[300];
size_t seckeylen = 300;
@ -3503,6 +3505,13 @@ void test_ecdsa_end_to_end(void) {
memset(&pubkey, 0, sizeof(pubkey));
CHECK(secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkeyc, pubkeyclen) == 1);
/* Verify negation changes the key and changes it back */
memcpy(&pubkey_tmp, &pubkey, sizeof(pubkey));
CHECK(secp256k1_ec_pubkey_negate(ctx, &pubkey_tmp) == 1);
CHECK(memcmp(&pubkey_tmp, &pubkey, sizeof(pubkey)) != 0);
CHECK(secp256k1_ec_pubkey_negate(ctx, &pubkey_tmp) == 1);
CHECK(memcmp(&pubkey_tmp, &pubkey, sizeof(pubkey)) == 0);
/* Verify private key import and export. */
CHECK(ec_privkey_export_der(ctx, seckey, &seckeylen, privkey, secp256k1_rand_bits(1) == 1));
CHECK(ec_privkey_import_der(ctx, privkey2, seckey, seckeylen) == 1);