def sec(self, compressed=True): '''returns the binary version of the SEC format''' if compressed: if not self.csec: serialized = ffi.new('unsigned char [33]') output_len = ffi.new('size_t *', 33) lib.secp256k1_ec_pubkey_serialize( GLOBAL_CTX, serialized, output_len, self.c, lib.SECP256K1_EC_COMPRESSED, ) self.csec = bytes(ffi.buffer(serialized, 33)) return self.csec else: if not self.usec: serialized = ffi.new('unsigned char [65]') output_len = ffi.new('size_t *', 65) lib.secp256k1_ec_pubkey_serialize( GLOBAL_CTX, serialized, output_len, self.c, lib.SECP256K1_EC_UNCOMPRESSED, ) self.usec = bytes(ffi.buffer(serialized, 65)) return self.usec
def der(self): if not self.der_cache: der = ffi.new('unsigned char[72]') der_length = ffi.new('size_t *', 72) lib.secp256k1_ecdsa_signature_serialize_der( GLOBAL_CTX, der, der_length, self.c) self.der_cache = bytes(ffi.buffer(der, der_length[0])) return self.der_cache
def __rmul__(self, coefficient): coef = coefficient % N new_key = ffi.new('secp256k1_pubkey *') s = self.sec(compressed=False) lib.secp256k1_ec_pubkey_parse(GLOBAL_CTX, new_key, s, len(s)) lib.secp256k1_ec_pubkey_tweak_mul(GLOBAL_CTX, new_key, coef.to_bytes(32, 'big')) serialized = ffi.new('unsigned char [65]') output_len = ffi.new('size_t *', 65) lib.secp256k1_ec_pubkey_serialize(GLOBAL_CTX, serialized, output_len, new_key, lib.SECP256K1_EC_UNCOMPRESSED) return self.__class__(usec=bytes(serialized))
def __add__(self, scalar): '''Multiplies scalar by generator, adds result to current point''' coef = scalar % N new_key = ffi.new('secp256k1_pubkey *') s = self.sec(compressed=False) lib.secp256k1_ec_pubkey_parse(GLOBAL_CTX, new_key, s, len(s)) lib.secp256k1_ec_pubkey_tweak_add(GLOBAL_CTX, new_key, coef.to_bytes(32, 'big')) serialized = ffi.new('unsigned char [65]') output_len = ffi.new('size_t *', 65) lib.secp256k1_ec_pubkey_serialize(GLOBAL_CTX, serialized, output_len, new_key, lib.SECP256K1_EC_UNCOMPRESSED) return self.__class__(usec=bytes(serialized))
def sign(self, z): secret = self.secret.to_bytes(32, 'big') msg = z.to_bytes(32, 'big') csig = ffi.new('secp256k1_ecdsa_signature *') if not lib.secp256k1_ecdsa_sign(GLOBAL_CTX, csig, msg, secret, ffi.NULL, ffi.NULL): raise RuntimeError('something went wrong with c signing') sig = Signature(c=csig) if not self.point.verify(z, sig): raise RuntimeError('something went wrong with signing') return sig
def __init__(self, der: Optional[bytes] = None, c: None = None) -> None: if der: self.der_cache = der self.c = ffi.new('secp256k1_ecdsa_signature *') if not lib.secp256k1_ecdsa_signature_parse_der( GLOBAL_CTX, self.c, der, len(der)): raise RuntimeError(f'badly formatted signature {der.hex()}') elif c: self.c = c self.der_cache = None else: raise RuntimeError('need der or c object')
def __init__(self, der=None, c=None): if der: self.der_cache = der self.c = ffi.new('secp256k1_ecdsa_signature *') if not lib.secp256k1_ecdsa_signature_parse_der( GLOBAL_CTX, self.c, der, len(der)): raise RuntimeError('badly formatted signature {}'.format( der.hex())) elif c: self.c = c self.der_cache = None else: raise RuntimeError('need der or c object')
def __init__(self, csec=None, usec=None): if usec: self.usec = usec self.csec = None sec_cache = usec elif csec: self.csec = csec self.usec = None sec_cache = csec else: raise RuntimeError('need a serialization') self.c = ffi.new('secp256k1_pubkey *') if not lib.secp256k1_ec_pubkey_parse(GLOBAL_CTX, self.c, sec_cache, len(sec_cache)): raise RuntimeError('libsecp256k1 produced error')