bug: fix paper wallet error when no secrets

This commit is contained in:
scgbckbone 2023-07-17 11:04:31 +02:00 committed by doc-hex
parent 99eb4b0345
commit 836980d9ce
3 changed files with 40 additions and 30 deletions

View File

@ -11,7 +11,8 @@
- Bugfix: remove label from Bitcoin Core `importdescriptors` export as it is no longer supported
with ranged descriptors in version `24.1` of Core.
- Bugfix: empty number during BIP-39 passphrase entry could cause crash.
- Bugfix: UX: Signing with BIP39 Passphrase showed master fingerprint as integer. Fixed to show hex.
- Bugfix: UX: Signing with BIP39 Passphrase showed master fingerprint as integer. Fixed to show hex.
- Bugfix: Fixed inability to generate paper wallet without secrets
## 5.1.2 - 2023-04-07

View File

@ -156,28 +156,29 @@ def sign_message_digest(digest, subpath, prompt, addr_fmt=AF_CLASSIC, pk=None):
if prompt:
dis.fullscreen(prompt, percent=.25)
with stash.SensitiveValues() as sv:
dis.progress_bar_show(.50)
if pk is None:
# if private key is provided, derivation subpath is ignored
# and provided private key is used for signing
if pk is None:
with stash.SensitiveValues() as sv:
# if private key is provided, derivation subpath is ignored
# and provided private key is used for signing
node = sv.derive_path(subpath)
dis.progress_bar_show(.50)
pk = node.privkey()
else:
node = ngu.hdnode.HDNode().from_chaincode_privkey(bytes(32), pk)
else:
node = ngu.hdnode.HDNode().from_chaincode_privkey(bytes(32), pk)
dis.progress_bar_show(.50)
addr = chains.current_chain().address(node, addr_fmt)
sv.register(pk)
ch = chains.current_chain()
addr = ch.address(node, addr_fmt)
dis.progress_bar_show(.75)
rv = ngu.secp256k1.sign(pk, digest, 0).to_bytes()
# AF_CLASSIC header byte base 31 is returned by default from ngu - NOOP
if addr_fmt != AF_CLASSIC:
header_byte, rs = rv[0], rv[1:]
# ngu only produces header base for compressed p2pkh, anyways get only rec_id
rec_id = (header_byte - 27) & 0x03
new_header_byte = rec_id + sv.chain.sig_hdr_base(addr_fmt=addr_fmt)
rv = bytes([new_header_byte]) + rs
dis.progress_bar_show(.75)
rv = ngu.secp256k1.sign(pk, digest, 0).to_bytes()
# AF_CLASSIC header byte base 31 is returned by default from ngu - NOOP
if addr_fmt != AF_CLASSIC:
header_byte, rs = rv[0], rv[1:]
# ngu only produces header base for compressed p2pkh, anyways get only rec_id
rec_id = (header_byte - 27) & 0x03
new_header_byte = rec_id + ch.sig_hdr_base(addr_fmt=addr_fmt)
rv = bytes([new_header_byte]) + rs
dis.progress_bar_show(1)

View File

@ -2,9 +2,12 @@
#
# Tests for paper-wallet feature
#
# Paper wallet features MUST work on both device with and without secrets.
# This module can and should be run with `-l` and without it.
#
import random
import pytest, time, struct, os, shutil, re
import pytest, time, struct, os, shutil, re, json
from pycoin.key.Key import Key
from pycoin.encoding import from_bytes_32
from base64 import b64encode
@ -13,18 +16,20 @@ from hashlib import sha256
from ckcc_protocol.protocol import CCProtocolPacker, CCProtoError, CCUserRefused
from ckcc_protocol.constants import *
from helpers import xfp2str
import json
from conftest import simulator_fixed_xfp, simulator_fixed_xprv
from bech32 import bech32_decode, convertbits, Encoding
@pytest.mark.parametrize('mode', [ "classic", 'segwit'])
@pytest.mark.parametrize('pdf', [ False, True])
def test_generate(mode, pdf, dev, cap_menu, pick_menu_item, goto_home, cap_story, need_keypress,
microsd_path, verify_detached_signature_file):
@pytest.mark.parametrize('mode', ["classic", 'segwit'])
@pytest.mark.parametrize('pdf', [False, True])
@pytest.mark.parametrize('netcode', ["XTN", "BTC"])
def test_generate(mode, pdf, netcode, dev, cap_menu, pick_menu_item, goto_home, cap_story,
need_keypress, microsd_path, verify_detached_signature_file, settings_set):
# test UX and operation of the 'bitcoin core' wallet export
mx = "Don't make PDF"
settings_set("chain", netcode)
goto_home()
pick_menu_item('Advanced/Tools')
try:
@ -111,7 +116,7 @@ def test_generate(mode, pdf, dev, cap_menu, pick_menu_item, goto_home, cap_story
assert hrp in {'tb', 'bc', 'bcrt'}
assert enc == Encoding.BECH32
decoded = convertbits(data[1:], 5, 8, False)[-20:]
addr = Key(hash160=bytes(decoded), is_compressed=True, netcode='XTN')
addr = Key(hash160=bytes(decoded), is_compressed=True, netcode=netcode)
elif hdr == 'Private key:': # for QR case
assert val == wif
elif 'Private key' in hdr and 'WIF=Wallet' in hdr:
@ -217,10 +222,14 @@ def test_dice_generate_failure_distribution(rolls, dev, cap_menu, pick_menu_item
"".join([str(random.SystemRandom().randint(1,6)) for _ in range(99)]),
"".join([str(random.SystemRandom().randint(1,6)) for _ in range(99)]),
])
def test_dice_generate(rolls, dev, cap_menu, pick_menu_item, goto_home, cap_story, need_keypress,
microsd_path, verify_detached_signature_file):
@pytest.mark.parametrize('netcode', ["XTN", "BTC"])
def test_dice_generate(rolls, netcode, dev, cap_menu, pick_menu_item, goto_home,
cap_story, need_keypress, microsd_path,
verify_detached_signature_file, settings_set):
# verify the math for dice rolling method
settings_set("chain", netcode)
goto_home()
pick_menu_item('Advanced/Tools')
try:
@ -281,12 +290,11 @@ def test_dice_generate(rolls, dev, cap_menu, pick_menu_item, goto_home, cap_stor
assert len(hx) == 1
val, = hx
k2 = Key(secret_exponent=from_bytes_32(a2b_hex(val)), is_compressed=True, netcode='XTN')
k2 = Key(secret_exponent=from_bytes_32(a2b_hex(val)), is_compressed=True, netcode=netcode)
assert addr == k2.address()
assert val == sha256(rolls.encode('ascii')).hexdigest()
os.unlink(path)
# EOF