While implementing BIP-352/374 Silent Payments for SeedSigner (PR #864), I found that the secp256k1 ctypes wrapper functions have no docstrings, which made it difficult to understand their behavior.
For example, ec_pubkey_negate():
from embit.util import secp256k1
help(secp256k1.ec_pubkey_negate)
# Output: wrapper(*args, **kwargs) - no documentation
Through trial and error, I discovered:
ec_pubkey_negate() returns a new negated point (does not modify in-place)
- Input must be a parsed pubkey (from
ec_pubkey_parse()), output is also parsed
- Need to call
ec_pubkey_serialize() to get bytes back
Similar clarity would help for other functions like ec_pubkey_tweak_add(), ec_pubkey_combine(), etc.
Example docstring:
def ec_pubkey_negate(pubkey):
"""
Negate a parsed public key (flip Y coordinate).
Args:
pubkey: Parsed pubkey from ec_pubkey_parse()
Returns:
New parsed pubkey (negated). Does NOT modify input.
Call ec_pubkey_serialize() to get bytes.
Example:
parsed = secp256k1.ec_pubkey_parse(pubkey_bytes)
negated = secp256k1.ec_pubkey_negate(parsed)
result = secp256k1.ec_pubkey_serialize(negated)
"""
This would help developers implementing advanced Bitcoin protocols (Silent Payments, MuSig, etc.).
While implementing BIP-352/374 Silent Payments for SeedSigner (PR #864), I found that the secp256k1 ctypes wrapper functions have no docstrings, which made it difficult to understand their behavior.
For example,
ec_pubkey_negate():Through trial and error, I discovered:
ec_pubkey_negate()returns a new negated point (does not modify in-place)ec_pubkey_parse()), output is also parsedec_pubkey_serialize()to get bytes backSimilar clarity would help for other functions like
ec_pubkey_tweak_add(),ec_pubkey_combine(), etc.Example docstring:
This would help developers implementing advanced Bitcoin protocols (Silent Payments, MuSig, etc.).