예제 #1
0
def get_subnode(node, i):
    # Public Child key derivation (CKD) algorithm of BIP32
    i_as_bytes = struct.pack(">L", i)

    if is_prime(i):
        raise Exception("Prime derivation not supported")

    # Public derivation
    data = node.public_key + i_as_bytes

    I64 = hmac.HMAC(key=node.chain_code, msg=data,
                    digestmod=hashlib.sha512).digest()
    I_left_as_exponent = string_to_number(I64[:32])

    node_out = proto_types.HDNodeType()
    node_out.depth = node.depth + 1
    node_out.child_num = i
    node_out.chain_code = I64[32:]
    node_out.fingerprint = fingerprint(node.public_key)

    # BIP32 magic converts old public key to new public point
    x, y = sec_to_public_pair(node.public_key)
    point = I_left_as_exponent * SECP256k1.generator + \
            Point(SECP256k1.curve, x, y, SECP256k1.order)

    if point == INFINITY:
        raise Exception("Point cannot be INFINITY")

    # Convert public point to compressed public key
    node_out.public_key = point_to_pubkey(point)

    return node_out
예제 #2
0
def public_ckd(public_node, n):
    if not isinstance(n, list):
        raise Exception('Parameter must be a list')

    node = proto_types.HDNodeType()
    node.CopyFrom(public_node)

    for i in n:
        node.CopyFrom(get_subnode(node, i))

    return node
예제 #3
0
    def load_device_by_xprv(self, xprv, pin, passphrase_protection, label,
                            language):
        if self.features.initialized:
            raise Exception(
                "Device is initialized already. Call wipe_device() and try again."
            )

        if xprv[0:4] not in ('xprv', 'tprv'):
            raise Exception("Unknown type of xprv")

        if len(xprv) < 100 and len(xprv) > 112:
            raise Exception("Invalid length of xprv")

        node = types.HDNodeType()
        data = tools.b58decode(xprv, None).encode('hex')

        if data[90:92] != '00':
            raise Exception("Contain invalid private key")

        checksum = hashlib.sha256(
            hashlib.sha256(binascii.unhexlify(
                data[:156])).digest()).hexdigest()[:8]
        if checksum != data[156:]:
            raise Exception("Checksum doesn't match")

        # version 0488ade4
        # depth 00
        # fingerprint 00000000
        # child_num 00000000
        # chaincode 873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508
        # privkey   00e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35
        # checksum e77e9d71

        node.depth = int(data[8:10], 16)
        node.fingerprint = int(data[10:18], 16)
        node.child_num = int(data[18:26], 16)
        node.chain_code = data[26:90].decode('hex')
        node.private_key = data[92:156].decode(
            'hex')  # skip 0x00 indicating privkey

        resp = self.call(
            proto.LoadDevice(node=node,
                             pin=pin,
                             passphrase_protection=passphrase_protection,
                             language=language,
                             label=label))
        self.init_device()
        return resp
예제 #4
0
def deserialize(xpub):
    data = tools.b58decode(xpub, None)

    if tools.Hash(data[:-4])[:4] != data[-4:]:
        raise Exception("Checksum failed")

    node = proto_types.HDNodeType()
    node.depth = struct.unpack('>B', data[4:5])[0]
    node.fingerprint = struct.unpack('>I', data[5:9])[0]
    node.child_num = struct.unpack('>I', data[9:13])[0]
    node.chain_code = data[13:45]

    key = data[45:-4]
    if key[0] == '\x00':
        node.private_key = key[1:]
    else:
        node.public_key = key

    return node