Exemple #1
0
    def schnorr_partial_sign(self, msg, privnonce, pubnonce_others,
                             raw=False, digest=hashlib.sha256):
        """
        Produce a partial Schnorr signature, which can be combined using
        schnorr_partial_combine to end up with a full signature that is
        verifiable using PublicKey.schnorr_verify.

        To combine pubnonces, use PublicKey.combine.

        Do not pass the pubnonce produced for the respective privnonce;
        combine the pubnonces from other signers and pass that instead.
        """
        if not HAS_SCHNORR:
            raise Exception("secp256k1_schnorr not enabled")

        msg32 = _hash32(msg, raw, digest)
        sig64 = ffi.new('char [64]')

        res = lib.secp256k1_schnorr_partial_sign(
            self.ctx, sig64, msg32, self.private_key,
            pubnonce_others, privnonce)
        if res <= 0:
            raise Exception('failed to partially sign ({})'.format(res))

        return bytes(ffi.buffer(sig64, 64))
Exemple #2
0
    def serialize(self, compressed=True):
        privser = ffi.new('char [279]')
        keylen = ffi.new('size_t *')

        res = lib.secp256k1_ec_privkey_export(
            self.ctx, privser, keylen, self.private_key, int(compressed))
        assert res == 1

        return bytes(ffi.buffer(privser, keylen[0]))
Exemple #3
0
    def ecdsa_serialize(self, raw_sig):
        len_sig = 74
        output = ffi.new('unsigned char[%d]' % len_sig)
        outputlen = ffi.new('size_t *', len_sig)

        res = lib.secp256k1_ecdsa_signature_serialize_der(
            self.ctx, output, outputlen, raw_sig)
        assert res == 1

        return bytes(ffi.buffer(output, outputlen[0]))
Exemple #4
0
    def deserialize(self, privkey_ser):
        privkey = ffi.new('char [32]')

        res = lib.secp256k1_ec_privkey_import(
            self.ctx, privkey, privkey_ser, len(privkey_ser))
        if not res:
            raise Exception("invalid private key")

        rawkey = bytes(ffi.buffer(privkey, 32))
        self.set_raw_privkey(rawkey)
        return self.private_key
Exemple #5
0
    def ecdsa_recoverable_serialize(self, recover_sig):
        if not HAS_RECOVERABLE:
            raise Exception("secp256k1_recovery not enabled")

        outputlen = 64
        output = ffi.new('unsigned char[%d]' % outputlen)
        recid = ffi.new('int *')

        lib.secp256k1_ecdsa_recoverable_signature_serialize_compact(
            self.ctx, output, recid, recover_sig)

        return bytes(ffi.buffer(output, outputlen)), recid[0]
Exemple #6
0
    def schnorr_sign(self, msg, raw=False, digest=hashlib.sha256):
        if not HAS_SCHNORR:
            raise Exception("secp256k1_schnorr not enabled")

        msg32 = _hash32(msg, raw, digest)
        sig64 = ffi.new('char [64]')

        signed = lib.secp256k1_schnorr_sign(
            self.ctx, sig64, msg32, self.private_key, ffi.NULL, ffi.NULL)
        assert signed == 1

        return bytes(ffi.buffer(sig64, 64))
Exemple #7
0
    def serialize(self, compressed=True):
        assert self.public_key, "No public key defined"

        len_compressed = 33 if compressed else 65
        res_compressed = ffi.new('char [%d]' % len_compressed)
        outlen = ffi.new('size_t *', len_compressed)

        serialized = lib.secp256k1_ec_pubkey_serialize(
            self.ctx, res_compressed, outlen, self.public_key, int(compressed))
        assert serialized == 1

        return bytes(ffi.buffer(res_compressed, len_compressed))
Exemple #8
0
    def ecdh(self, scalar):
        assert self.public_key, "No public key defined"
        if not HAS_ECDH:
            raise Exception("secp256k1_ecdh not enabled")
        if not isinstance(scalar, bytes) or len(scalar) != 32:
            raise TypeError('scalar must be composed of 32 bytes')

        result = ffi.new('char [32]')

        res = lib.secp256k1_ecdh(self.ctx, result, self.public_key, scalar)
        if not res:
            raise Exception('invalid scalar ({})'.format(res))

        return bytes(ffi.buffer(result, 32))
Exemple #9
0
    def schnorr_partial_combine(self, schnorr_sigs):
        """Combine multiple Schnorr partial signatures."""
        if not HAS_SCHNORR:
            raise Exception("secp256k1_schnorr not enabled")
        assert len(schnorr_sigs) > 0

        sig64 = ffi.new('char [64]')
        sig64sin = []
        for sig in schnorr_sigs:
            if not isinstance(sig, bytes):
                raise TypeError('expected bytes, got {}'.format(type(sig)))
            sig64sin.append(ffi.new('char []', sig))

        res = lib.secp256k1_schnorr_partial_combine(
            self.ctx, sig64, sig64sin, len(sig64sin))
        if res <= 0:
            raise Exception('failed to combine signatures ({})'.format(res))

        return bytes(ffi.buffer(sig64, 64))