Skip to content

Commit 180d853

Browse files
committed
fix miniscript/multisig
1 parent 5f533aa commit 180d853

1 file changed

Lines changed: 45 additions & 61 deletions

File tree

hwilib/devices/coldcard.py

Lines changed: 45 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -126,72 +126,56 @@ def sign_tx(self, tx: PSBT) -> PSBT:
126126
"""
127127
self.device.check_mitm()
128128

129-
# Get this devices master key fingerprint
130-
xpub = self.device.send_recv(CCProtocolPacker.get_xpub('m/0\''), timeout=None)
131-
master_fp = get_xpub_fingerprint(xpub)
132-
133-
# For multisigs, we may need to do multiple passes if we appear in an input multiple times
134-
passes = 1
135-
for psbt_in in tx.inputs:
136-
our_keys = 0
137-
for key in psbt_in.hd_keypaths.keys():
138-
keypath = psbt_in.hd_keypaths[key]
139-
if keypath.fingerprint == master_fp and key not in psbt_in.partial_sigs:
140-
our_keys += 1
141-
if our_keys > passes:
142-
passes = our_keys
143-
144-
for _ in range(passes):
145-
# Get psbt in hex and then make binary
146-
tx.convert_to_v0()
147-
fd = io.BytesIO(base64.b64decode(tx.serialize()))
148-
149-
# learn size (portable way)
150-
sz = fd.seek(0, 2)
151-
fd.seek(0)
152-
153-
left = sz
154-
chk = sha256()
155-
for pos in range(0, sz, MAX_BLK_LEN):
156-
here = fd.read(min(MAX_BLK_LEN, left))
157-
if not here:
158-
break
159-
left -= len(here)
160-
result = self.device.send_recv(CCProtocolPacker.upload(pos, sz, here))
161-
assert result == pos
162-
chk.update(here)
163-
164-
# do a verify
165-
expect = chk.digest()
166-
result = self.device.send_recv(CCProtocolPacker.sha256())
167-
assert len(result) == 32
168-
if result != expect:
169-
raise DeviceFailureError("Wrong checksum:\nexpect: %s\n got: %s" % (b2a_hex(expect).decode('ascii'), b2a_hex(result).decode('ascii')))
170-
171-
# start the signing process
172-
ok = self.device.send_recv(CCProtocolPacker.sign_transaction(sz, expect), timeout=None)
173-
assert ok is None
174-
if self.device.is_simulator:
175-
self.device.send_recv(CCProtocolPacker.sim_keypress(b'y'))
176-
177-
print("Waiting for OK on the Coldcard...", file=sys.stderr)
178-
179-
while 1:
180-
time.sleep(0.250)
181-
done = self.device.send_recv(CCProtocolPacker.get_signed_txn(), timeout=None)
182-
if done is None:
183-
continue
129+
# Get psbt in hex and then make binary
130+
tx.convert_to_v0()
131+
fd = io.BytesIO(base64.b64decode(tx.serialize()))
132+
133+
# learn size (portable way)
134+
sz = fd.seek(0, 2)
135+
fd.seek(0)
136+
137+
left = sz
138+
chk = sha256()
139+
for pos in range(0, sz, MAX_BLK_LEN):
140+
here = fd.read(min(MAX_BLK_LEN, left))
141+
if not here:
184142
break
143+
left -= len(here)
144+
result = self.device.send_recv(CCProtocolPacker.upload(pos, sz, here))
145+
assert result == pos
146+
chk.update(here)
147+
148+
# do a verify
149+
expect = chk.digest()
150+
result = self.device.send_recv(CCProtocolPacker.sha256())
151+
assert len(result) == 32
152+
if result != expect:
153+
raise DeviceFailureError("Wrong checksum:\nexpect: %s\n got: %s" % (b2a_hex(expect).decode('ascii'), b2a_hex(result).decode('ascii')))
154+
155+
# start the signing process
156+
ok = self.device.send_recv(CCProtocolPacker.sign_transaction(sz, expect), timeout=None)
157+
assert ok is None
158+
if self.device.is_simulator:
159+
self.device.send_recv(CCProtocolPacker.sim_keypress(b'y'))
160+
161+
print("Waiting for OK on the Coldcard...", file=sys.stderr)
162+
163+
while 1:
164+
time.sleep(0.250)
165+
done = self.device.send_recv(CCProtocolPacker.get_signed_txn(), timeout=None)
166+
if done is None:
167+
continue
168+
break
185169

186-
if len(done) != 2:
187-
raise DeviceFailureError('Failed: %r' % done)
170+
if len(done) != 2:
171+
raise DeviceFailureError('Failed: %r' % done)
188172

189-
result_len, result_sha = done
173+
result_len, result_sha = done
190174

191-
result = self.device.download_file(result_len, result_sha, file_number=1)
175+
result = self.device.download_file(result_len, result_sha, file_number=1)
192176

193-
tx = PSBT()
194-
tx.deserialize(base64.b64encode(result).decode())
177+
tx = PSBT()
178+
tx.deserialize(base64.b64encode(result).decode())
195179

196180
return tx
197181

0 commit comments

Comments
 (0)