Skip to content

Conversation

apoelstra
Copy link
Contributor

I have an application which uses summed secret keys as a keysplitting mechanism. To use this with BIP32, I would like to negate the public parent key, which would give the following result:

  • one of the key shards is the negative parent key, the other the child key
  • the "summed key" is then the BIP32 tweak

In my case I can change my application to use a difference of keys rather than sum of keys, but this adds another way for the user to get things wrong, especially when used with a more "symmetric" key split where it's unclear which of the two shards ought to be negated.

@sipa
Copy link
Contributor

sipa commented Aug 24, 2016

Concept ACK if you also add a secp256k1_ec_privkey_negate. Also, what about using the secp256k1_ec_*_tweak_negate name, for consistency with _tweak_add and _tweak_mul ?

@apoelstra
Copy link
Contributor Author

Sure, I can add a privkey negate.

As for the tweak_ names, I had thought that the "tweak" was the extra parameter, not the original element -- you are multiplying by a tweak, or adding a tweak.

@apoelstra
Copy link
Contributor Author

Added negate_privkey.

That test failure is a randomness test failure, I think it's just a fluke.

@instagibbs
Copy link

change PR title to match new functionality?

@apoelstra apoelstra changed the title Add secp256k1_ec_pubkey_negate Add secp256k1_ec_pubkey_negate and secp256k1_ec_privkey_negate Aug 26, 2016
@instagibbs
Copy link

This is failing a test.

@apoelstra
Copy link
Contributor Author

kicked travis

VERIFY_CHECK(ctx != NULL);
ARG_CHECK(pubkey != NULL);

ret = secp256k1_pubkey_load(ctx, &p, pubkey);
Copy link
Contributor

Choose a reason for hiding this comment

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

The pubkey tweak functions zeroize the output on load failure, this code would operate on uninitialized memory.

Copy link
Contributor

Choose a reason for hiding this comment

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

for consistency, memset(pubkey, 0, sizeof(*pubkey)); after the load, unless you've got an argument that its bad to clear it completely (in which case we should change it everywhere)

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);

Copy link
Contributor

Choose a reason for hiding this comment

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

Test a null argument and test a bad pubkey object.

@gmaxwell
Copy link
Contributor

No strong view, but these are multiplicative tweaks with a fixed tweak value of -1.

Concept ACK, will ACK with nits fixed.

@apoelstra
Copy link
Contributor Author

Fixed nits.

@gmaxwell
Copy link
Contributor

@apoelstra ping see above: "for consistency, memset(pubkey, 0, sizeof(*pubkey)); after the load, unless you've got an argument that its bad to clear it completely (in which case we should change it everywhere)"

@apoelstra
Copy link
Contributor Author

Sorry, I forgot to address this. My argument was that the pubkey going into this function is a public key, isn't secret, and there is no need to zeroize it. But this is true even for pubkey_tweak_add, so I guess the purpose of the zeroing is to turn any invalid pubkey into a "standard invalid pubkey", which seems like a sane functional behaviour.

Added the memset.

@voisine
Copy link
Contributor

voisine commented Dec 20, 2016

in the case of BIP32, a single private key in combination with a master public key exposes all private keys. So, it's possible that a "public" key may indeed be secret.

@gmaxwell
Copy link
Contributor

so I guess the purpose of the zeroing is to turn any invalid pubkey into a "standard invalid pubkey",

exactly.

@voisine Nope, unrelated. The issue there is the extended public key. The EC point being described here does not have the properties you're referring to-- it cannot be used to convert extend another private key.

@gmaxwell
Copy link
Contributor

ACK.

@sipa
Copy link
Contributor

sipa commented Mar 22, 2017

utACK

@sipa sipa merged commit 8e48aa6 into bitcoin-core:master Mar 22, 2017
sipa added a commit that referenced this pull request Mar 22, 2017
…y_negate`

8e48aa6 Add `secp256k1_ec_pubkey_negate` and `secp256k1_ec_privkey_negate` (Andrew Poelstra)

Tree-SHA512: 28eeca0b04001958ad86b3c802e33a13273514e9e9802d5b358fd577dc95421a2cffb5591716bea10300717f742f0941c465b9df71dbb4c66d174c643887e06f
@apoelstra apoelstra deleted the negate-pubkey branch June 19, 2017 13:21
achow101 added a commit to bitcoin/bitcoin that referenced this pull request May 9, 2025
1ee698f test: refactor: negate signature-s using libsecp256k1 (Sebastian Falbesoner)

Pull request description:

  This small PR gets rid of manual mod-n inversion of the ECDSA signature-s part in unit tests (introduced a long time ago in #5256, triggered by bitcoin-core/secp256k1#69) by using secp256k1 instead. The function wasn't available at that time, but was introduced about three years later, see bitcoin-core/secp256k1#408. Note that as the name suggests, `secp256k1_ec_seckey_negate` is meant to be used for secret keys, but it obviously works in general for scalars modulo the group order.

ACKs for top commit:
  achow101:
    ACK 1ee698f
  laanwj:
    Code review ACK 1ee698f
  w0xlt:
    ACK 1ee698f
  rkrux:
    tACK 1ee698f

Tree-SHA512: dc36ea1572b538d11ae34e1871f310a1cda8083ffb753e93e7ee9d56e91ebd8ec78d35758dfb700254720914b734ef7a071eeef71b6239f19e1e2fb289fb5435
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants