Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edge branch #388

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
991965a
Token diff
doc-hex Jul 4, 2024
e1ff15b
edits
doc-hex Jul 4, 2024
98db85f
restored
doc-hex Jul 4, 2024
eef1f6d
switch to space in word menu
doc-hex Jul 4, 2024
89405e8
mistake
doc-hex Jul 4, 2024
a798e96
ui: newline in visualize bip21
scgbckbone Jul 4, 2024
d2920d1
taproot singlesig
scgbckbone Jun 7, 2024
f618af1
miniscript/tapscript; BSMS; show multisig/miniscript addresses in exp…
scgbckbone Jun 12, 2024
a18938c
unspend( & ranged unspendable taproot internal keys
scgbckbone Jun 25, 2024
bf67c5a
updated
doc-hex Jul 4, 2024
47754d1
Signed for q1 release.
doc-hex Jul 4, 2024
f7f41fe
New release: 2024-07-04T1500-v6.3.3QX
doc-hex Jul 4, 2024
e7f8a1a
Signed for mk4 release.
doc-hex Jul 4, 2024
5b2772a
New release: 2024-07-04T1501-v6.3.3X
doc-hex Jul 4, 2024
bb87cdd
correct edge versions
scgbckbone Jul 4, 2024
427cf89
taproot singlesig
scgbckbone Jun 7, 2024
b1fe5e1
miniscript/tapscript; BSMS; show multisig/miniscript addresses in exp…
scgbckbone Jun 12, 2024
ef2c5a7
unspend( & ranged unspendable taproot internal keys
scgbckbone Jun 25, 2024
06dde5a
updated
doc-hex Jul 4, 2024
fce5542
New release: 2024-07-04T1500-v6.3.3QX
doc-hex Jul 4, 2024
9b4cc26
New release: 2024-07-04T1501-v6.3.3X
doc-hex Jul 4, 2024
99ab403
correct edge versions
scgbckbone Jul 4, 2024
e3f7561
fixes after master rebase
scgbckbone Sep 17, 2024
e344bac
Merge branch 'new_edge' into edge_Sep2024_test
scgbckbone Sep 17, 2024
1a41164
bugfix: fill_policy; always keep subderivation path in policy string
scgbckbone Nov 20, 2024
49de639
tests
scgbckbone Nov 21, 2024
35c16c1
big boy test
scgbckbone Nov 26, 2024
b07fb8a
Merge pull request #435 from scgbckbone/edge_Sep2024_test
doc-hex Dec 14, 2024
053c916
bugfix: single key miniscript wallets
scgbckbone Nov 29, 2024
1cdb090
bugfix: UX checkmark was still on the Miniscript menu item even after…
scgbckbone Dec 15, 2024
5b08eae
do NOT allow to enable/disable Seed Vault while in temporary seed mode
scgbckbone Sep 26, 2024
e794ecf
Fix grammar error
henrialb Sep 29, 2024
23d252f
bugfix: bless firmware causes hanging progress bar
scgbckbone Oct 14, 2024
ed5f54e
deltamode & secure notes and passwords
scgbckbone Oct 16, 2024
dc8732a
deltamode & Seed Vault
scgbckbone Oct 15, 2024
51c1b1d
do not allow to delete current active tmp seed from seed vault and pu…
scgbckbone Sep 27, 2024
4b93075
Mk4: export descriptor as simple QR
scgbckbone Sep 23, 2024
480b2d7
save bytes drv_entro.py
scgbckbone Oct 22, 2024
55ea381
improve Wipe LFS UX message
scgbckbone Nov 15, 2024
8ed0e05
provide generalized nfc reader function (saving bytes)
scgbckbone Nov 8, 2024
ead0f00
prevent ownership yikes
scgbckbone Nov 15, 2024
500ac35
changelog
scgbckbone Dec 16, 2024
3c8252d
NFC code optimizations
scgbckbone Dec 16, 2024
54f3fcd
fixes
scgbckbone Dec 17, 2024
5802827
versions
scgbckbone Dec 17, 2024
6e52fd8
remove changes not included from ChangeLog
scgbckbone Dec 17, 2024
21daefd
Q fix
scgbckbone Dec 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/signit.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def doit(keydir, outfn=None, build_dir=None, high_water=False,
pubkey_num=pubkey_num,
timestamp=timestamp(backdate) )

assert FW_MIN_LENGTH <= hdr.firmware_length <= FW_MAX_LENGTH, hdr.firmware_length
assert FW_MIN_LENGTH <= hdr.firmware_length <= FW_MAX_LENGTH_MK4, hdr.firmware_length

if hw_compat & MK_3_OK:
# actual file length limited by size of SPI flash area reserved to txn data/uploads
Expand Down
3 changes: 2 additions & 1 deletion docs/limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ We will summarize transaction outputs as "change" back into same wallet, however
- `p2wsh-p2sh`: _redeemScript_ (which is: `0x00 + 0x20 + sha256(witnessScript)`), and
_witnessScript_ (which contains the multisig script)
- `p2wsh`: only _witnessScript_ (which contains the actual multisig script)

- `p2tr`(keypath singlesig): no _redeemScript_, no _witnessScript_ and output key MUST commit to an unspendable script path as follows `Q = P + int(hashTapTweak(bytes(P)))G`
- `p2tr`(scriptpath multisig): _taproot_merkle_root_ and _leaf_script_ more info in docs/taproot.md

# Derivation Paths

Expand Down
27 changes: 27 additions & 0 deletions docs/miniscript.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Miniscript

**COLDCARD<sup>&reg;</sup>** Mk4 experimental `EDGE` versions
support Miniscript and MiniTapscript.

## Import/Export

* `Settings` -> `Miniscript` -> `Import from file`
* only [descriptors](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki) allowed for import
* `Settings` -> `Miniscript` -> `<name>` -> `Descriptors`
* only [descriptors](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki) are exported
* export extended keys to participate in miniscript:
* `Advanced/Tools` -> `Export Wallet` -> `Generic JSON`
* `Settings` -> `Multisig Wallets` -> `Export XPUB`

## Address Explorer

Same as with basic multisig. After miniscript wallet is imported,
item with `<name>` is added to `Address Explorer` menu.


## Limitations
* no duplicate keys in miniscript (at least change indexes in subderivation has to be different)
* subderivation may be omitted during the import - default `<0;1>/*` is implied
* only keys with key origin info `[xfp/p/a/t/h]xpub`
* maximum number of keys allowed in segwit v0 miniscript is 20
* check MiniTapscript limitations in `docs/taproot.md`
75 changes: 75 additions & 0 deletions docs/taproot.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Taproot

**COLDCARD<sup>&reg;</sup>** Mk4 experimental `EDGE` versions
support Schnorr signatures ([BIP-0340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki)),
Taproot ([BIP-0341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki))
and Tapscript ([BIP-0342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki)) support.

## Output script (a.k.a address) generation

If the spending conditions do not require a script path, the output key MUST commit to an unspendable script path.
`Q = P + int(hashTapTweak(bytes(P)))G` a.k.a internal key MUST be tweaked by `TapTweak` tagged hash of itself. If
the spending conditions require script path, internal key MUST be tweaked by `TapTweak` tagged hash of tree merkle root.

Addresses in `Address Explorer` for `p2tr` are generated with above-mentioned methods. Outputs `scriptPubkeys` in PSBT
MUST be generated with above-mentoned methods to be considered change.

## Allowed descriptors

1. Single signature wallet without script path: `tr(key)`
2. Tapscript multisig with internal key and up to 8 leaf scripts:
* `tr(internal_key, sortedmulti_a(2,@0,@1))`
* `tr(internal_key, pk(@0))`
* `tr(internal_key, {sortedmulti_a(2,@0,@1),pk(@2)})`
* `tr(internal_key, {or_d(pk(@0),and_v(v:pkh(@1),older(1000))),pk(@2)})`

## Provably unspendable internal key

There are few methods to provide/generate provably unspendable internal key, if users wish to only use tapscript script path.

1. **(recommended)** Origin-less extended key serialization with H from [BIP-0341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs) as BIP-32 key and random chaincode.

`tr(xpub/<0:1>/*, sortedmulti_a(2,@0,@1))` which is the same thing as `tr(xpub, sortedmulti_a(2,@0,@1))` because `/<0;1>/*` is implied if not derivation path not provided.

2. **(recommended)** Use `unspend(` [notation](https://gist.github.com/sipa/06c5c844df155d4e5044c2c8cac9c05e#unspendable-keys). Has to be ranged.

`tr(unspend(77ec0c0fdb9733e6a3c753b1374c4a465cba80dff52fc196972640a26dd08b76)/<0:1>/*, sortedmulti_a(2,@0,@1))`

3. use **static** provably unspendable internal key H from [BIP-0341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs).

`tr(50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0, sortedmulti_a(2,@0,@1))`

4. use COLDCARD specific placeholder `@` to let HWW pick a fresh integer r in the range 0...n-1 uniformly at random and use `H + rG` as internal key. COLDCARD will not store r and therefore user is not able to prove to other party how the key was generated and whether it is actually unspendable.

`tr(r=@, sortedmulti_a(MofN))`

5. pick a fresh integer r in the range 0...n-1 uniformly at random yourself and provide that in the descriptor. COLDCARD generates internal key with `H + rG`. It is possible to prove to other party that this internal key does not have a known discrete logarithm with respect to G by revealing r to a verifier who can then reconstruct how the internal key was created.

`tr(r=77ec0c0fdb9733e6a3c753b1374c4a465cba80dff52fc196972640a26dd08b76, sortedmulti_a(2,@0,@1))`

Option 3. leaks the information that key path spending is not possible and therefore is not recommended privacy-wise.
Options 4. and 5. are problematic to some extent as internal key is static. Use recommended options 1. and 2. if the fact that internal key is unspendable should remain private.


## Limitations

### Tapscript Limitations

In current version only `TREE` of max depth 4 is allowed (max 8 leaf script allowed).
Taproot single leaf multisig has artificial limit of max 32 signers (M=N=32).
Number of keys in taptree is limited to 32.

If Coldcard can sign by both key path and script path - key path has precedence.

### PSBT Requirements

PSBT provider MUST provide following Taproot specific input fields in PSBT:
1. `PSBT_IN_TAP_BIP32_DERIVATION` with all the necessary keys with their leaf hashes and derivation (including XFP). Internal key has to be specified here with empty leaf hashes.
2. `PSBT_IN_TAP_INTERNAL_KEY` MUST match internal key provided in `PSBT_IN_TAP_BIP32_DERIVATION`
3. `PSBT_IN_TAP_MERKLE_ROOT` MUST be empty if there is no script path. Otherwise it MUST match what Coldcard can calculate from registered descriptor.
4. `PSBT_IN_TAP_LEAF_SCRIPT` MUST be specified if there is a script path. Currently MUST be of length 1 (only one script allowed)

PSBT provider MUST provide following Taproot specific output fields in PSBT:
1. `PSBT_OUT_TAP_BIP32_DERIVATION` with all the necessary keys with their leaf hashes and derivation (including XFP). Internal key has to be specified here with empty leaf hashes.
2. `PSBT_OUT_TAP_INTERNAL_KEY` must match internal key provided in `PSBT_OUT_TAP_BIP32_DERIVATION`
3. `PSBT_OUT_TAP_TREE` with depth, leaf version and script defined. Currently only one script is allowed.
45 changes: 45 additions & 0 deletions releases/EdgeChangeLog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Change Log

## Warning: Edge Version

```diff
- This preview version of firmware has not yet been qualified
- and tested to the same standard as normal Coinkite products.
- It is recommended only for developers and early adopters
- for experimental use. DO NOT use for large Bitcoin amounts.
```

This lists the changes in the most recent EDGE firmware, for each hardware platform.

# Shared Improvements - Both Mk4 and Q

- Bugfix: Complex miniscript wallets with keys in policy that are not in strictly ascending order were incorrectly filled
upon load from settings. All users on versions `6.2.2X`+ needs to update.
- Bugfix: Single key miniscript descriptor support
- Enhancement: Hide Secure Notes & Passwords in Deltamode. Wipe seed if notes menu accessed.
- Enhancement: Hide Seed Vault in Deltamode. Wipe seed if Seed Vault menu accessed.
- Bugfix: Do not allow to enable/disable Seed Vault feature when in temporary seed mode
- Bugfix: Bless Firmware causes hanging progress bar
- Bugfix: Prevent yikes in ownership search
- Change: Do not allow to purge settings of current active tmp seed when deleting it from Seed Vault


# Mk4 Specific Changes

## 6.3.4X - 2024-07-04

- all updates from `5.4.0`
- Enhancement: Export single sig descriptor with simple QR


# Q Specific Changes

## 6.3.4QX - 2024-07-04

- all updates from version `1.3.0Q`
- Bugfix: Properly re-draw status bar after Restore Master on COLDCARD without master seed.


# Release History

- [`History-Edge.md`](History-Edge.md)
73 changes: 73 additions & 0 deletions releases/History-Edge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
## Warning: Edge Version

```diff
- This preview version of firmware has not yet been qualified
- and tested to the same standard as normal Coinkite products.
- It is recommended only for developers and early adopters
- for experimental use. DO NOT use for large Bitcoin amounts.
```

## 6.3.3X & 6.3.3QX Shared Improvements - Both Mk4 and Q (2024-07-04)

- New Feature: Ranged provably unspendable keys and `unspend(` support for Taproot descriptors
- New Feature: Address ownership for miniscript and tapscript wallets
- Enhancement: Address explorer simplified UI for tapscript addresses
- Bugfix: Constant `AFC_BECH32M` incorrectly set `AFC_WRAPPED` and `AFC_BECH32`.
- Bugfix: Trying to set custom URL for NFC push transaction caused yikes

### Mk4 Specific Changes

- Bugfix: Fix yikes displaying BIP-85 WIF when both NFC and VDisk are OFF
- Bugfix: Fix inability to export change addresses when both NFC and Vdisk id OFF
- Bugfix: In BIP-39 words menu, show space character rather than Nokia-style placeholder
which could be confused for an underscore.

### Q Specific Changes

- Enhancement: Miniscript and (BB)Qr codes
- Bugfix: Properly clear LCD screen after simple QR code is shown


## 6.2.2X - 2024-01-18

- New Feature: Miniscript [USB interface](https://github.com/Coldcard/ckcc-protocol/blob/master/README.md#miniscript)
- New Feature: Named miniscript imports. Wrap descriptor in json
`{"name:"n0", "desc":"<descriptor>"}` with `name` key to use this name instead of the
filename. Mostly usefull for USB and NFC imports that have no file, in which case name
was created from descriptor checksum.
- Enhancement: Allow keys with same origin, differentiated only by change index derivation
in miniscript descriptor.
- Enhancement: HSM `wallet` rule enabled for miniscript
- Enhancement: Add `msas` in to the `share_addrs` HSM [rule](https://coldcard.com/docs/hsm/rules/)
to be able to check miniscript addresses in HSM mode.
- Enhancement: HW Accelerated AES CTR for BSMS and passphrase saver
- Bugfix: Do not allow to import duplicate miniscript
wallets (thanks to [AnchorWatch](https://www.anchorwatch.com/))
- Bugfix: Saving passphrase on SD Card caused a freeze that required reboot

## 6.2.1X - 2023-10-26

- New Feature: Enroll Miniscript wallet via USB (requires ckcc `v1.4.0`)
- New Feature: Temporary Seed from COLDCARD encrypted backup
- Enhancement: Add current temporary seed to Seed Vault from within Seed Vault menu.
If current active temporary seed is not saved yet, `Add current tmp` menu item is
present in Seed Vault menu.
- Reorg: `12 Words` menu option preferred on the top of the menu in all the seed menus
- Enhancement: Mainnet/Testnet separation. Only show wallets for current active chain.
- contains all the changes from the newest stable `5.2.0-mk4` firmware

## 6.1.0X - 2023-06-20

- New Feature: Miniscript and MiniTapscript support (`docs/miniscript.md`)
- Enhancement: Tapscript up to 8 leafs
- Address explorer display refined slightly (cosmetic)

## 6.0.0X - 2023-05-12

- New Feature: Taproot keyspend & Tapscript multisig `sortedmulti_a` (tree depth = 0)
- New Feature: Support BIP-0129 Bitcoin Secure Multisig Setup (BSMS).
Both Coordinator and Signer roles are supported.
- Enhancement: change Key Origin Information export format in multisig `addresses.csv` according to [BIP-0380](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki#key-expressions)
`(m=0F056943)/m/48'/1'/0'/2'/0/0` --> `[0F056943/48'/1'/0'/2'/0/0]`
- Bugfix: correct `scriptPubkey` parsing for segwit v1-v16
- Bugfix: do not infer segwit just by availability of `PSBT_IN_WITNESS_UTXO` in PSBT
18 changes: 12 additions & 6 deletions releases/Next-ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@ This lists the new changes that have not yet been published in a normal release.

# Shared Improvements - Both Mk4 and Q

# Mk4 Specific Changes

- tbd
- Enhancement: Hide Secure Notes & Passwords in Deltamode. Wipe seed if notes menu accessed.
- Enhancement: Hide Seed Vault in Deltamode. Wipe seed if Seed Vault menu accessed.
- Bugfix: Sometimes see a struck screen after _Verifying..._ in boot up sequence.
On Q, result is blank screen, on Mk4, result is three-dots screen.
- Bugfix: Do not allow to enable/disable Seed Vault feature when in temporary seed mode
- Bugfix: Bless Firmware causes hanging progress bar
- Bugfix: Prevent yikes in ownership search
- Change: Do not allow to purge settings of current active tmp seed when deleting it from Seed Vault


## 5.4.? - 2024-??-??
# Mk4 Specific Changes

- tbd
## 5.4.1 - 2024-??-??

- Enhancement: Export single sig descriptor with simple QR


# Q Specific Changes

## 1.3.?Q - 2024-??-??
## 1.3.1Q - 2024-??-??

- Bugfix: Properly re-draw status bar after Restore Master on COLDCARD without master seed.
26 changes: 21 additions & 5 deletions shared/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from export import make_bitcoin_core_wallet, generate_wasabi_wallet, generate_generic_export
from export import generate_unchained_export, generate_electrum_wallet
from files import CardSlot, CardMissingError, needs_microsd
from public_constants import AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH, MAX_TXN_LEN_MK4
from public_constants import AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH, AF_P2TR, MAX_TXN_LEN_MK4
from glob import settings
from pincodes import pa
from menu import start_chooser, MenuSystem, MenuItem
Expand Down Expand Up @@ -872,6 +872,14 @@ async def start_login_sequence():
# is early in boot process
print("XFP save failed: %s" % exc)

# Version warning before HSM is offered
if version.is_edge and not ckcc.is_simulator():
await ux_show_story(
"This preview version of firmware has not yet been qualified and "
"tested to the same standard as normal Coinkite products."
"\n\nIt is recommended only for developers and early adopters for experimental use. "
"DO NOT use for large Bitcoin amounts.", title="Edge Version")

dis.draw_status(xfp=settings.get('xfp'))

# If HSM policy file is available, offer to start that,
Expand All @@ -889,6 +897,14 @@ async def start_login_sequence():
await ar.interact()
except: pass

if pa.is_deltamode():
# pretend Secure Notes & Passwords is disabled
# pretend SeedVault is disabled
try:
settings.remove_key("secnap")
settings.master_set("seedvault", False)
except: pass

if version.has_nfc and settings.get('nfc', 0):
# Maybe allow NFC now
import nfc
Expand Down Expand Up @@ -1014,7 +1030,7 @@ async def export_xpub(label, _2, item):
path = "m"
addr_fmt = AF_CLASSIC
else:
remap = {44:0, 49:1, 84:2}[mode]
remap = {44:0, 49:1, 84:2,86:3}[mode]
_, path, addr_fmt = chains.CommonDerivations[remap]
path = path.format(account='{acct}', coin_type=chain.b44_cointype, change=0, idx=0)[:-4]

Expand Down Expand Up @@ -1095,7 +1111,7 @@ def ss_descriptor_export_story(addition="", background="", acct=True):
async def ss_descriptor_skeleton(_0, _1, item):
# Export of descriptor data (wallet)
int_ext, addition, f_pattern = None, "", "descriptor.txt"
allowed_af = [AF_P2WPKH, AF_CLASSIC, AF_P2WPKH_P2SH]
allowed_af = [AF_P2WPKH, AF_CLASSIC, AF_P2WPKH_P2SH, AF_P2TR]
if item.arg:
int_ext, allowed_af, ll, f_pattern = item.arg
addition = " for " + ll
Expand Down Expand Up @@ -1392,7 +1408,7 @@ async def wipe_filesystem(*A):
if not await ux_confirm('''\
Erase internal filesystem and rebuild it. Resets contents of internal flash area \
used for settings, address search cache, and HSM config file. Does not affect funds, \
or seed words but will reset settings used with other BIP-39 passphrases. \
or seed words but will reset settings used with other temporary seeds & BIP-39 passphrases. \
Does not affect MicroSD card, if any.'''):
return

Expand Down Expand Up @@ -1731,7 +1747,7 @@ async def bless_flash(*a):
pa.greenlight_firmware()

# redraw our screen
dis.show()
dis.busy_bar(False) # includes dis.show()


def is_psbt(filename):
Expand Down
Loading