Example #1
0
def _derive_public_child(pubkey, chaincode, index):
    """A.k.a CKDpub, in bip-0032.

    :param pubkey: The parent's (compressed) public key, as bytes
    :param chaincode: The parent's chaincode, as bytes
    :param index: The index of the node to derive, as int

    :return: (child_pubkey, child_chaincode)
    """
    assert isinstance(pubkey, bytes) and isinstance(chaincode, bytes)
    assert not index & HARDENED_INDEX
    # payload is the I from the BIP. Index is 32 bits unsigned int, BE.
    payload = hmac.new(chaincode, pubkey + index.to_bytes(4, "big"),
                       hashlib.sha512).digest()
    try:
        tmp_pub = coincurve.PublicKey.from_secret(payload[:32])
    except ValueError:
        raise BIP32DerivationError("Invalid private key at index {}, try the "
                                   "next one!".format(index))
    parent_pub = coincurve.PublicKey(pubkey)
    try:
        child_pub = coincurve.PublicKey.combine_keys([tmp_pub, parent_pub])
    except ValueError:
        raise BIP32DerivationError("Invalid public key at index {}, try the "
                                   "next one!".format(index))
    return child_pub.format(), payload[32:]
    def FromBytes(cls,
                  point_bytes: bytes) -> IPoint:
        """
        Construct class from point bytes.

        Args:
            point_bytes (bytes): Point bytes

        Returns:
            IPoint: IPoint object
        """
        if len(point_bytes) == EcdsaKeysConst.PUB_KEY_UNCOMPRESSED_BYTE_LEN - 1:
            return cls(coincurve.PublicKey(EcdsaKeysConst.PUB_KEY_UNCOMPRESSED_PREFIX + point_bytes))
        if len(point_bytes) == EcdsaKeysConst.PUB_KEY_COMPRESSED_BYTE_LEN:
            return cls(coincurve.PublicKey(point_bytes))
        raise ValueError("Invalid point bytes")
def diffi_hellman(pub_key, priv_key):
    logging.info(f"This is the public_key in function {pub_key}")

    alice_coin_priv =  coincurve.PrivateKey.from_hex(priv_key)
    #bob_coin_priv = coincurve.PrivateKey.from_hex(bob_priv)
    pub = coincurve.PublicKey(pub_key)
    logging.info(f"This is the public_key after parsing {pub}")
    logging.info(f"This is the public_key after parsing {pub.public_key}")
    return binascii.hexlify(alice_coin_priv.ecdh(pub.public_key))
Example #4
0
def verify_signature(signature: bytes, message_hash: bytes,
                     public_key: bytes) -> bool:
    recoverable: bool = is_signature_recoverable(signature)
    public_key_object = coincurve.PublicKey(public_key)

    if recoverable:
        public_key_object_from_signature = coincurve.PublicKey.from_signature_and_message(
            signature, message_hash, hasher=None)
        return public_key_object == public_key_object_from_signature
    else:
        public_key_object.verify(signature, message_hash, hasher=None)
Example #5
0
def verify_recover_secp256k1_bc(signature,
                                req,
                                hasher=coincurve.utils.sha256,
                                context=GLOBAL_CONTEXT):
    msg_hash = hasher(req) if hasher is not None else req
    rec_sig = coincurve.ecdsa.deserialize_recoverable(signature)
    public_key = coincurve.PublicKey(coincurve.ecdsa.recover(req, rec_sig))
    n_sig = coincurve.ecdsa.recoverable_convert(rec_sig)

    if not lib.secp256k1_ecdsa_verify(context.ctx, n_sig, msg_hash,
                                      public_key.public_key):
        raise RuntimeError("Failed to verify SECP256K1 bitcoin signature")
Example #6
0
def derive_public_key(per_commitment_point, base_point):
    k = sha256(per_commitment_point + base_point).digest()

    pub1 = coincurve.PrivateKey(secret=k).public_key
    pub2 = coincurve.PublicKey(data=base_point)
    pub = pub2.combine([pub1])

    #pub1 = secp256k1.PrivateKey(privkey=k, raw=True).pubkey
    #pub2 = secp256k1.PublicKey(base_point, raw=True)
    #pub = pub2.combine([pub1.public_key])

    return pub.format()
Example #7
0
 def _check_signature(self, siglist):
     # check identity scheme
     scheme = self.get('id')
     if scheme != b'v4':
         raise SignatureError('unsupported identity scheme "' + scheme + '"')
     pubkey = self.get('secp256k1')
     if len(pubkey) != 33:
         raise SignatureError('invalid public key length')
     pubkey = coincurve.PublicKey(pubkey)
     # verify against the public key from k/v data
     sigdata = sha3.keccak_256(rlp.encode(siglist)).digest()
     if not pubkey.verify(_signature_to_der(self._sig), sigdata, hasher=None):
         raise SignatureError('invalid signature')
Example #8
0
    def __init__(self, innerkey):
        # We accept either 33-bytes raw keys, or an EC PublicKey as returned
        # by coincurve
        if isinstance(innerkey, bytes):
            if innerkey[0] in [2, 3] and len(innerkey) == 33:
                innerkey = coincurve.PublicKey(innerkey)
            else:
                raise ValueError(
                    "Byte keys must be 33-byte long starting from either 02 or 03"
                )

        elif not isinstance(innerkey, coincurve.keys.PublicKey):
            raise ValueError(
                "Key must either be bytes or coincurve.keys.PublicKey")
        self.key = innerkey
def multiply(s, pub, return_serialized=True):
    '''Input binary compressed pubkey P(33 bytes)
    and scalar s(32 bytes), return s*P.
    The return value is a binary compressed public key,
    or a PublicKey object if return_serialized is False.
    Note that the called function does the type checking
    of the scalar s.
    ('raw' options passed in)
    '''
    newpub = secp256k1.PublicKey(pub)
    #see note to "tweak_mul" function in podle.py
    res = newpub.multiply(s)
    if not return_serialized:
        return res
    return res.format()
Example #10
0
def perform_complaint(sgx, t, poly_name, public_key,
                      corrupted_secret_key_contribution):
    response = sgx.complaint_response(poly_name, 1)
    share, dh_key = response["share"], response["dh_key"]
    ecdh_key = coincurve.PublicKey(
        bytes.fromhex("04" + public_key[2:])).multiply(
            coincurve.keys.PrivateKey.from_hex(dh_key).secret).format(
                compressed=False)[1:33]
    decrypted_key = decrypt(bytes.fromhex(corrupted_secret_key_contribution),
                            ecdh_key)
    mult_g2 = sgx.mult_g2(decrypted_key)
    share = share.split(':')
    assert share == mult_g2

    verification_vector_mult = response["verification_vector_mult"]
    assert len(verification_vector_mult) == t
    def FromBytes(cls, key_bytes: bytes) -> IPublicKey:
        """
        Construct class from key bytes.

        Args:
            key_bytes (bytes): Key bytes

        Returns:
            IPublicKey: IPublicKey object

        Raises:
            ValueError: If key bytes are not valid
        """
        try:
            return cls(coincurve.PublicKey(key_bytes))
        except ValueError as ex:
            raise ValueError("Invalid public key bytes") from ex
Example #12
0
def multiply(s, pub, usehex, rawpub=True, return_serialized=True):
    '''Input binary compressed pubkey P(33 bytes)
    and scalar s(32 bytes), return s*P.
    The return value is a binary compressed public key,
    or a PublicKey object if return_serialized is False.
    Note that the called function does the type checking
    of the scalar s.
    ('raw' options passed in)
    '''
    newpub = secp256k1.PublicKey(pub)
    #see note to "tweak_mul" function in podle.py
    if sys.version_info >= (3, 0):
        res = newpub.multiply(native_bytes(s))
    else:
        res = newpub.multiply(bytes_to_native_str(s))
    if not return_serialized:
        return res
    return res.format()
Example #13
0
def getNUMS(index=0) -> Point:
    """
    Nothing Up My Sleeve

    Taking secp256k1's G as a seed,
    either in compressed or uncompressed form,
    append "index" as a byte, and append a second byte "counter"
    try to create a new NUMS base point from the sha256 of that
    bytestring. Loop counter and alternate compressed/uncompressed
    until finding a valid curve point. The first such point is
    considered as "the" NUMS base point alternative for this index value.
    The search process is of course deterministic/repeatable, so
    it's fine to just store a list of all the correct values for
    each index, but for transparency left in code for initialization
    by any user.
    """

    for G in [
            B.encode_pubkey(B.G, 'bin_compressed'),
            B.encode_pubkey(B.G, 'bin')
    ]:
        # Using latin-1 since its used in BTC
        seed = G + chr(index).encode('utf-8')
        for counter in range(256):
            seed_c = seed + chr(counter).encode('utf-8')
            hash_seed = hashlib.sha256(seed_c).digest()

            # Every x-coord on the curve has two y-values, encoded
            # in compressed form with 02/03 parity byte. We just
            # choose the former
            claimed_point: bytes = chr(2).encode('utf-8') + hash_seed

            try:
                # Check to see if its a valid public key
                C.PublicKey(claimed_point)
                return B.encode_pubkey(claimed_point, 'decimal')
            except:
                continue

    raise Exception('NUMS generation inconceivable')
Example #14
0
def ecies_decrypt(privkey, encrypted):
    if len(privkey) == 33 and privkey[-1] == 1:
        privkey = privkey[:32]
    encrypted = base64.b64decode(encrypted)
    if len(encrypted) < 85:
        raise Exception('invalid ciphertext: length')
    magic = encrypted[:4]
    if magic != ECIES_MAGIC_BYTES:
        raise ECIESDecryptionError()
    ephemeral_pubkey = encrypted[4:37]
    try:
        testR = secp256k1.PublicKey(ephemeral_pubkey)
    except:
        raise ECIESDecryptionError()
    ciphertext = encrypted[37:-32]
    mac = encrypted[-32:]
    ecdh_key = btc.multiply(privkey, ephemeral_pubkey)
    key = hashlib.sha512(ecdh_key).digest()
    iv, key_e, key_m = key[0:16], key[16:32], key[32:]
    if mac != hmac.new(key_m, encrypted[:-32], hashlib.sha256).digest():
        raise ECIESDecryptionError()
    return aes_decrypt(key_e, ciphertext, iv=iv)
Example #15
0
def ecdsa_raw_verify(msg, pub, sig, usehex, rawmsg=False):
    '''Take the binary message msg and binary signature sig,
    and verify it against the pubkey pub.
    If rawmsg is True, no sha256 hash is applied to msg before verifying.
    In this case, msg must be a precalculated hash (256 bit).
    If rawmsg is False, the secp256k1 lib will hash the message as part
    of the ECDSA-SHA256 verification algo.
    Return value: True if the signature is valid for this pubkey, False
    otherwise.
    Since the arguments may come from external messages their content is
    not guaranteed, so return False on any parsing exception.
    '''
    try:
        if rawmsg:
            assert len(msg) == 32
        newpub = secp256k1.PublicKey(pub)
        if rawmsg:
            retval = newpub.verify(sig, msg, hasher=None)
        else:
            retval = newpub.verify(sig, msg)
    except:
        return False
    return retval
Example #16
0
def is_valid_pubkey(pubkey, usehex, require_compressed=False):
    """ Returns True if the serialized pubkey is a valid secp256k1
    pubkey serialization or False if not; returns False for an
    uncompressed encoding if require_compressed is True.
    """
    # sanity check for public key
    # see https://github.com/bitcoin/bitcoin/blob/master/src/pubkey.h
    if require_compressed:
        valid_uncompressed = False
    elif len(pubkey) == 65 and pubkey[:1] in (b'\x04', b'\x06', b'\x07'):
        valid_uncompressed = True
    else:
        valid_uncompressed = False

    if not ((len(pubkey) == 33 and pubkey[:1] in (b'\x02', b'\x03'))
            or valid_uncompressed):
        return False
    # serialization is valid, but we must ensure it corresponds
    # to a valid EC point:
    try:
        dummy = secp256k1.PublicKey(pubkey)
    except:
        return False
    return True
Example #17
0
def pub_to_pub(pub: bytes, compressed: bool = True):
    return coincurve.PublicKey(pub).format(compressed=compressed)
Example #18
0
def add_pubkeys(pubkeys, usehex):
    '''Input a list of binary compressed pubkeys
    and return their sum as a binary compressed pubkey.'''
    pubkey_list = [secp256k1.PublicKey(x) for x in pubkeys]
    r = secp256k1.PublicKey.combine_keys(pubkey_list)
    return r.format()
Example #19
0
def blind_group_element(pubkey, blind: Secret) -> PublicKey:
    pubkey = coincurve.PublicKey(data=pubkey.to_bytes())
    blinded = pubkey.multiply(blind.to_bytes(), update=False)
    return PublicKey(blinded.format(compressed=True))
Example #20
0
 def verify(self):
     return coincurve.PublicKey(self._source).verify(
         self._signature, self.to_signable())
Example #21
0
def podle_PublicKey(P):
    """Returns a PublicKey object from a binary string
    """
    return secp256k1.PublicKey(P)
Example #22
0
 def node_addr(self):
     pubkey = coincurve.PublicKey(self.get('secp256k1'))
     pubkey = pubkey.format(compressed=False)
     return sha3.keccak_256(pubkey[1:]).digest()
Example #23
0
    def decode(cls, b):
        hrp, data = bech32_decode(b)
        if not hrp:
            raise ValueError("Bad bech32 checksum")

        # BOLT #11:
        #
        # A reader MUST fail if it does not understand the `prefix`.
        if not hrp.startswith('ln'):
            raise ValueError("Does not start with ln")

        data = u5_to_bitarray(data)

        # Final signature 65 bytes, split it off.
        if len(data) < 65 * 8:
            raise ValueError("Too short to contain signature")
        sigdecoded = data[-65 * 8:].tobytes()
        data = bitstring.ConstBitStream(data[:-65 * 8])

        inv = Invoice()
        inv.pubkey = None

        m = re.search(r'[^\d]+', hrp[2:])
        if m:
            inv.currency = m.group(0)
            amountstr = hrp[2 + m.end():]
            # BOLT #11:
            #
            # A reader SHOULD indicate if amount is unspecified, otherwise it MUST
            # multiply `amount` by the `multiplier` value (if any) to derive the
            # amount required for payment.
            if amountstr != '':
                inv.amount = unshorten_amount(amountstr)

        inv.date = data.read(35).uint

        while data.pos != data.len:
            tag, tagdata, data = pull_tagged(data)

            # BOLT #11:
            #
            # A reader MUST skip over unknown fields, an `f` field with unknown
            # `version`, or a `p`, `h`, `n` or `r` field which does not have
            # `data_length` 52, 52, 53 or 82 respectively.
            data_length = len(tagdata) / 5

            if tag == 'r':
                inv.route_hints = RouteHintSet.from_bytes(
                    trim_to_bytes(tagdata))
                continue
                if data_length != 82:
                    inv.unknown_tags.append((tag, tagdata))
                    continue

                tagbytes = trim_to_bytes(tagdata)

                inv.tags.append(('r', (tagbytes[0:33], tagbytes[33:41],
                                       tagdata[41 * 8:49 * 8].intbe,
                                       tagdata[49 * 8:51 * 8].intbe)))
            elif tag == 'f':
                fallback = parse_fallback(tagdata, inv.currency)
                if fallback:
                    inv.tags.append(('f', fallback))
                else:
                    # Incorrect version.
                    inv.unknown_tags.append((tag, tagdata))
                    continue

            elif tag == 'd':
                inv.tags.append(('d', trim_to_bytes(tagdata).decode('utf-8')))

            elif tag == 'h':
                if data_length != 52:
                    inv.unknown_tags.append((tag, tagdata))
                    continue
                inv.tags.append(('h', trim_to_bytes(tagdata)))

            elif tag == 'x':
                inv.tags.append(('x', tagdata.uint))

            elif tag == 'p':
                if data_length != 52:
                    inv.unknown_tags.append((tag, tagdata))
                    continue
                inv.paymenthash = trim_to_bytes(tagdata)

            elif tag == 'n':
                if data_length != 53:
                    inv.unknown_tags.append((tag, tagdata))
                    continue
                inv.pubkey = coincurve.PublicKey(trim_to_bytes(tagdata))

            elif tag == 'c':
                inv.min_final_cltv_expiry = tagdata.uint
            else:
                inv.unknown_tags.append((tag, tagdata))

        # BOLT #11:
        #
        # A reader MUST check that the `signature` is valid (see the `n` tagged
        # field specified below).
        if inv.pubkey:  # Specified by `n`
            # BOLT #11:
            #
            # A reader MUST use the `n` field to validate the signature instead of
            # performing signature recovery if a valid `n` field is provided.
            inv.signature = inv.pubkey.ecdsa_deserialize_compact(
                sigdecoded[0:64])
            if not inv.pubkey.ecdsa_verify(
                    bytearray([ord(c)
                               for c in hrp]) + data.tobytes(), inv.signature):
                raise ValueError('Invalid signature')
        else:  # Recover pubkey from signature.
            inv.signature = coincurve.ecdsa.deserialize_recoverable(
                sigdecoded[0:65])
            inv.pubkey = coincurve.PublicKey.from_signature_and_message(
                sigdecoded[0:65],
                bytearray([ord(c) for c in hrp]) + data.tobytes())

        return inv
Example #24
0
def ecdh(k, rk):
    k = coincurve.PrivateKey(secret=k.rawkey)
    rk = coincurve.PublicKey(data=rk.serializeCompressed())
    a = k.ecdh(rk.public_key)
    return Secret(a)
Example #25
0
 def verify(self):
     return coincurve.PublicKey(codecs.decode(self._source, 'hex')).verify(
         codecs.decode(self._signature, 'hex'), self.to_signable())
Example #26
0
 def from_bytes(cls, data: bytes) -> "Secp256k1PublicKey":
     impl = coincurve.PublicKey(data)
     return cls(impl)
Example #27
0
def ecdh(k, rk):
    k = coincurve.PrivateKey(secret=k)
    rk = coincurve.PublicKey(data=rk)
    a = k.ecdh(rk.public_key)
    return a
Example #28
0
def verify(message, pub, signature):
    pub = cc.PublicKey(pub, context=cc.GLOBAL_CONTEXT)
    return pub.verify(signature, message, hasher=REGULAR_HASH_FUNCTION)
Example #29
0
 def verify(self, signature, message, public_key=None):
     if public_key is not None:
         return coincurve.PublicKey(public_key).verify(signature, message)
     return self.__public_key__.verify(signature, message)
Example #30
0
def pub_to_pub(pub, compressed=True):
    return coincurve.PublicKey(pub).format(compressed=compressed)