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

Recommended way to negate points #10

Open
AdamISZ opened this issue Sep 24, 2022 · 1 comment
Open

Recommended way to negate points #10

AdamISZ opened this issue Sep 24, 2022 · 1 comment

Comments

@AdamISZ
Copy link
Contributor

AdamISZ commented Sep 24, 2022

I know that the underlying secp256k1 library exposes a pubkey_negate :

https://github.com/bitcoin-core/secp256k1/blob/6f6cab9989a4d3f4a28e3cdbfacc4e3e1e55c843/include/secp256k1.h#L668

but at first thought, it's not that surprising that this isn't exposed in this binding, since we have the most fundamental operations: combine (add pubkeys together) and tweak_mul, tweak_add.

Still, it leaves me a little uncertain what the best way to do -P is. In the now "legacy" compressed encoding we can flip 02/03 starting byte. That feels like an icky way to do it (even if it wasn't the case that we're now tending to use the new Schnorr style 32 byte pubkeys); mathematical operations on keys shouldn't be executed by manipulating their encodings.

Another obvious thought is: use scalar mult (so tweak_mul) with the value "-1", but that is N-1 where N is the group order and it also feels very bad to be introducing that kind of calculation outside the library/binding.

Am I missing an obvious way to do it?

@moonsettler
Copy link

Ran into the same issue, negation, subtraction was easy enough.
https://replit.com/@moonsettler/BlindSchnorrMuSig#secp.py

from secp256k1 import PrivateKey, PublicKey

class PublicKeyExt(PublicKey):

    def __neg__(self):
        serialized = self.serialize()
        first_byte, remainder = serialized[:1], serialized[1:]
        # flip odd/even byte
        first_byte = {b"\x03": b"\x02", b"\x02": b"\x03"}[first_byte]
        return PublicKey(first_byte + remainder, raw=True)
 
 PublicKey.__neg__ = PublicKeyExt.__neg__
 
 class PrivateKeyExt(PrivateKey):
 
    def __neg__(self):
      order = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 #order of secp256k1 group
      neg_num=_int_to_bytes(order-_bytes_to_int(self.private_key, 'big'), 32, 'big')
      return PrivateKey(neg_num, raw=True)
 
 PrivateKey.__neg__ = PrivateKeyExt.__neg__

Now I need the inverse modulo (secp256k1_scalar_inverse?)...

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

No branches or pull requests

2 participants