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
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
def verify_message(address, signature, message): """ See http://www.secg.org/download/aid-780/sec1-v2.pdf for the math """ curve = ecdsa.curves.SECP256k1.curve # curve_secp256k1 G = ecdsa.curves.SECP256k1.generator order = G.order() # extract r,s from signature if len(signature) != 65: raise BaseException("Wrong signature") r, s = util.sigdecode_string(signature[1:], order) nV = ord(signature[0]) if nV < 27 or nV >= 35: raise BaseException("Bad encoding") if nV >= 31: compressed = True nV -= 4 else: compressed = False recid = nV - 27 # 1.1 x = r + (recid / 2) * order # 1.3 alpha = (x * x * x + curve.a() * x + curve.b()) % curve.p() beta = ecdsa.numbertheory.square_root_mod_prime(alpha, curve.p()) y = beta if (beta - recid) % 2 == 0 else curve.p() - beta # 1.4 the constructor checks that nR is at infinity R = ellipticcurve.Point(curve, x, y, order) # 1.5 compute e from message: h = sha256(sha256(message_magic(message)).digest()).digest() e = util.string_to_number(h) minus_e = -e % order # 1.6 compute Q = r^-1 (sR - eG) inv_r = numbertheory.inverse_mod(r, order) Q = inv_r * (s * R + minus_e * G) public_key = ecdsa.VerifyingKey.from_public_point(Q, curve=ecdsa.curves.SECP256k1) # check that Q is the public key public_key.verify_digest(signature[1:], h, sigdecode=ecdsa.util.sigdecode_string) if address: address_type = int(binascii.hexlify(tools.b58decode(address, None)[0]), 16) addr = tools.public_key_to_bc_address('\x04' + public_key.to_string(), address_type, compress=compressed) if address != addr: raise Exception("Invalid signature")
def load_device_by_xprv(self, xprv, pin, passphrase_protection, label): 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.version = int(data[0:8], 16) 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='english', label=label)) self.init_device() return isinstance(resp, proto.Success)