Open AdamISZ opened 2 years ago
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?)...
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?